use of org.aion.base.util.ByteArrayWrapper 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();
}
}
use of org.aion.base.util.ByteArrayWrapper in project aion by aionnetwork.
the class TxPoolA0 method snapshot.
public synchronized List<TX> snapshot() {
List<TX> rtn = new ArrayList<>();
sortTxn();
removeTimeoutTxn();
int cnt_txSz = 0;
long cnt_nrg = 0;
Set<ByteArrayWrapper> snapshotSet = new HashSet<>();
for (Entry<BigInteger, Map<ByteArrayWrapper, TxDependList<ByteArrayWrapper>>> e : this.getFeeView().entrySet()) {
if (LOG.isTraceEnabled()) {
LOG.trace("snapshot fee[{}]", e.getKey().toString());
}
Map<ByteArrayWrapper, TxDependList<ByteArrayWrapper>> tpl = e.getValue();
for (Entry<ByteArrayWrapper, TxDependList<ByteArrayWrapper>> pair : tpl.entrySet()) {
// Check the small nonce tx must been picked before put the high nonce tx
ByteArrayWrapper dependTx = pair.getValue().getDependTx();
if (dependTx == null || snapshotSet.contains(dependTx)) {
boolean firstTx = true;
for (ByteArrayWrapper bw : pair.getValue().getTxList()) {
ITransaction itx = this.getMainMap().get(bw).getTx();
cnt_txSz += itx.getEncoded().length;
cnt_nrg += itx.getNrgConsume();
if (LOG.isTraceEnabled()) {
LOG.trace("from:[{}] nonce:[{}] txSize: txSize[{}] nrgConsume[{}]", itx.getFrom().toString(), new BigInteger(1, itx.getNonce()).toString(), itx.getEncoded().length, itx.getNrgConsume());
}
if (cnt_txSz < blkSizeLimit && cnt_nrg < blkNrgLimit.get()) {
try {
rtn.add((TX) itx.clone());
if (firstTx) {
snapshotSet.add(bw);
firstTx = false;
}
} catch (Exception ex) {
ex.printStackTrace();
if (LOG.isErrorEnabled()) {
LOG.error("TxPoolA0.snapshot exception[{}], return [{}] TX", ex.toString(), rtn.size());
}
return rtn;
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("Reach blockLimit: txSize[{}], nrgConsume[{}], tx#[{}]", cnt_txSz, cnt_nrg, rtn.size());
}
return rtn;
}
}
}
}
}
if (LOG.isInfoEnabled()) {
LOG.info("TxPoolA0.snapshot return [{}] TX, poolSize[{}]", rtn.size(), getMainMap().size());
}
return rtn;
}
use of org.aion.base.util.ByteArrayWrapper in project aion by aionnetwork.
the class TxPoolA0 method add.
@Override
public synchronized List<TX> add(List<TX> txl) {
List<TX> newPendingTx = new ArrayList<>();
Map<ByteArrayWrapper, TXState> mainMap = new HashMap<>();
for (TX tx : txl) {
ByteArrayWrapper bw = ByteArrayWrapper.wrap(tx.getHash());
if (this.getMainMap().get(bw) != null) {
if (LOG.isWarnEnabled()) {
LOG.warn("The tx hash existed in the pool! [{}]", ByteUtils.toHexString(bw.getData()));
}
continue;
}
if (LOG.isTraceEnabled()) {
LOG.trace("Put tx into mainMap: hash:[{}] tx:[{}]", ByteUtils.toHexString(bw.getData()), tx.toString());
}
mainMap.put(bw, new TXState(tx));
BigInteger txNonce = tx.getNonceBI();
BigInteger bn = getBestNonce(tx.getFrom());
if (bn != null && txNonce.compareTo(bn) < 1) {
if (LOG.isDebugEnabled()) {
LOG.debug("repay tx, do snapshot!");
}
snapshot();
}
AbstractMap.SimpleEntry<ByteArrayWrapper, BigInteger> entry = this.getAccView(tx.getFrom()).getMap().get(txNonce);
if (entry != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("repay tx, remove previous tx!");
}
List oldTx = remove(Collections.singletonList(this.getMainMap().get(entry.getKey()).getTx()));
if (oldTx != null && !oldTx.isEmpty()) {
newPendingTx.add((TX) oldTx.get(0));
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("new tx!");
}
newPendingTx.add(tx);
}
setBestNonce(tx.getFrom(), txNonce);
}
this.getMainMap().putAll(mainMap);
return newPendingTx;
}
use of org.aion.base.util.ByteArrayWrapper in project aion by aionnetwork.
the class AionRepositoryDummy method updateBatch.
public void updateBatch(HashMap<ByteArrayWrapper, AccountState> stateCache, HashMap<ByteArrayWrapper, IContractDetails<DataWord>> detailsCache) {
for (ByteArrayWrapper hash : stateCache.keySet()) {
AccountState accountState = stateCache.get(hash);
IContractDetails<DataWord> contractDetails = detailsCache.get(hash);
if (accountState.isDeleted()) {
worldState.remove(hash);
detailsDB.remove(hash);
logger.debug("delete: [{}]", Hex.toHexString(hash.getData()));
} else {
if (accountState.isDirty() || contractDetails.isDirty()) {
detailsDB.put(hash, contractDetails);
accountState.setStateRoot(contractDetails.getStorageHash());
accountState.setCodeHash(h256(contractDetails.getCode()));
worldState.put(hash, accountState);
if (logger.isDebugEnabled()) {
logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]", Hex.toHexString(hash.getData()), accountState.getNonce(), accountState.getBalance(), contractDetails.getStorage());
}
}
}
}
stateCache.clear();
detailsCache.clear();
}
use of org.aion.base.util.ByteArrayWrapper in project aion by aionnetwork.
the class BlockPropagationHandler method propagateNewBlock.
// assumption here is that blocks propagated have unique hashes
public void propagateNewBlock(final AionBlock block) {
if (block == null)
return;
ByteArrayWrapper hashWrapped = new ByteArrayWrapper(block.getHash());
synchronized (this.cacheMap) {
this.cacheMap.put(hashWrapped, true);
}
this.p2pManager.getActiveNodes().values().forEach(n -> {
if (log.isDebugEnabled())
log.debug("<sending-new-block=" + block.getShortHash() + " to=" + n.getIdShort() + ">");
this.p2pManager.send(n.getIdHash(), new BroadcastNewBlock(block));
});
}
Aggregations