use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class ApiAion method getTransactionByBlockHashAndIndex.
public AionTransaction getTransactionByBlockHashAndIndex(byte[] hash, long index) {
AionBlock pBlk = this.getBlockByHash(hash);
if (pBlk == null) {
if (LOG.isErrorEnabled()) {
LOG.error("ApiAion.getTransactionByBlockHashAndIndex - can't find the block by the block hash");
}
return null;
}
List<AionTransaction> txList = pBlk.getTransactionsList();
AionTransaction tx = txList.get((int) index);
if (tx == null) {
if (LOG.isErrorEnabled()) {
LOG.error("Can't find the transaction!");
}
return null;
}
TxRecpt receipt = this.getTransactionReceipt(tx.getHash());
// TODO
if (receipt == null) {
throw new NullPointerException();
}
tx.setBlockNumber(pBlk.getNumber());
tx.setBlockHash(pBlk.getHash());
tx.setTxIndexInBlock(index);
tx.setNrgConsume(receipt.nrgUsed);
return tx;
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionBlockchainImpl method createNewBlock.
public synchronized AionBlock createNewBlock(AionBlock parent, List<AionTransaction> txs, boolean waitUntilBlockTime) {
long time = System.currentTimeMillis() / THOUSAND_MS;
if (parent.getTimestamp() >= time) {
time = parent.getTimestamp() + 1;
while (waitUntilBlockTime && System.currentTimeMillis() / THOUSAND_MS <= time) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
}
}
long energyLimit = this.chainConfiguration.calcEnergyLimit(parent.getHeader());
A0BlockHeader.Builder headerBuilder = new A0BlockHeader.Builder();
headerBuilder.withParentHash(parent.getHash()).withCoinbase(minerCoinbase).withNumber(parent.getNumber() + 1).withTimestamp(time).withExtraData(minerExtraData).withTxTrieRoot(calcTxTrie(txs)).withEnergyLimit(energyLimit);
AionBlock block = new AionBlock(headerBuilder.build(), txs);
block.getHeader().setDifficulty(ByteUtil.bigIntegerToBytes(this.chainConfiguration.getDifficultyCalculator().calculateDifficulty(block.getHeader(), parent.getHeader()), DIFFICULTY_BYTES));
/*
* Begin execution phase
*/
pushState(parent.getHash());
track = repository.startTracking();
track.rollback();
RetValidPreBlock preBlock = generatePreBlock(block);
/*
* Calculate the gas used for the included transactions
*/
long totalEnergyUsed = 0;
for (AionTxExecSummary summary : preBlock.summaries) {
totalEnergyUsed = totalEnergyUsed + summary.getNrgUsed().longValueExact();
}
byte[] stateRoot = getRepository().getRoot();
popState();
/*
* End execution phase
*/
Bloom logBloom = new Bloom();
for (AionTxReceipt receipt : preBlock.receipts) {
logBloom.or(receipt.getBloomFilter());
}
block.seal(preBlock.txs, calcTxTrie(preBlock.txs), stateRoot, logBloom.getData(), calcReceiptsTrie(preBlock.receipts), totalEnergyUsed);
return block;
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionBlockchainImpl method recoverWorldState.
@Override
public synchronized boolean recoverWorldState(IRepository repository, long blockNumber) {
AionRepositoryImpl repo = (AionRepositoryImpl) repository;
Map<Long, AionBlock> dirtyBlocks = new HashMap<>();
AionBlock other;
// find all the blocks missing a world state
long index = blockNumber;
do {
other = repo.getBlockStore().getChainBlockByNumber(index);
// cannot recover if no valid states exist (must build from genesis)
if (other == null) {
return false;
} else {
dirtyBlocks.put(other.getNumber(), other);
index--;
}
} while (!repo.isValidRoot(other.getStateRoot()));
// sync to the last correct state
repo.syncToRoot(other.getStateRoot());
// remove the last added block because it has a correct world state
index = other.getNumber();
dirtyBlocks.remove(index);
LOG.info("Corrupt world state at block #" + blockNumber + ". Rebuilding from block #" + index + ".");
index++;
// rebuild world state for dirty blocks
while (!dirtyBlocks.isEmpty()) {
LOG.info("Rebuilding block #" + index + ".");
other = dirtyBlocks.remove(index);
this.add(other, true);
index++;
}
// update the repository
repo.flush();
// return a flag indicating if the recovery worked
if (repo.isValidRoot(repo.getBlockStore().getChainBlockByNumber(blockNumber).getStateRoot())) {
return true;
} else {
// reverting back one block
LOG.info("Rebuild FAILED. Reverting to previous block.");
RecoveryUtils.Status status = RecoveryUtils.revertTo(this, blockNumber - 1);
return (status == RecoveryUtils.Status.SUCCESS) && repo.isValidRoot(repo.getBlockStore().getChainBlockByNumber(blockNumber - 1).getStateRoot());
}
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionBlockStore method getListHashesEndWith.
@Override
public List<byte[]> getListHashesEndWith(byte[] hash, long number) {
List<AionBlock> blocks = getListBlocksEndWith(hash, number);
List<byte[]> hashes = new ArrayList<>(blocks.size());
for (IAionBlock b : blocks) {
hashes.add(b.getHash());
}
return hashes;
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionPoW method createNewBlockTemplate.
/**
* Creates a new block template.
*/
protected synchronized void createNewBlockTemplate() {
if (!shutDown.get()) {
if (!config.getConsensus().getMining()) {
return;
}
// it be used in DDOS?
if (this.syncMgr.getNetworkBestBlockNumber() - blockchain.getBestBlock().getNumber() > syncLimit) {
return;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Creating a new block template");
}
AionBlock bestBlock = blockchain.getBlockByNumber(blockchain.getBestBlock().getNumber());
List<AionTransaction> txs = pendingState.getPendingTransactions();
AionBlock newBlock = blockchain.createNewBlock(bestBlock, txs, false);
EventConsensus ev = new EventConsensus(EventConsensus.CALLBACK.ON_BLOCK_TEMPLATE);
ev.setFuncArgs(Collections.singletonList(newBlock));
eventMgr.newEvent(ev);
// update last timestamp
lastUpdate.set(System.currentTimeMillis());
}
}
Aggregations