use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionBlockchainImpl method getListOfBodiesByHashes.
@Override
public List<byte[]> getListOfBodiesByHashes(List<byte[]> hashes) {
List<byte[]> bodies = new ArrayList<>(hashes.size());
for (byte[] hash : hashes) {
AionBlock block = getBlockStore().getBlockByHash(hash);
if (block == null) {
break;
}
bodies.add(block.getEncodedBody());
}
return bodies;
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionHub method loadBlockchain.
private void loadBlockchain() {
this.repository.getBlockStore().load();
AionBlock bestBlock = this.repository.getBlockStore().getBestBlock();
boolean recovered = true;
boolean bestBlockShifted = true;
int countRecoveryAttempts = 0;
// fix the trie if necessary
while (// the best block was updated after recovery attempt
bestBlockShifted && // allow 5 recovery attempts
(countRecoveryAttempts < 5) && // recover only for non-null blocks
bestBlock != null && !this.repository.isValidRoot(bestBlock.getStateRoot())) {
long bestBlockNumber = bestBlock.getNumber();
byte[] bestBlockRoot = bestBlock.getStateRoot();
recovered = this.blockchain.recoverWorldState(this.repository, bestBlockNumber);
if (recovered) {
bestBlock = this.repository.getBlockStore().getBestBlock();
// checking is the best block has changed since attempting recovery
if (bestBlock == null) {
bestBlockShifted = true;
} else {
bestBlockShifted = // block number changed
!(bestBlockNumber == bestBlock.getNumber()) || // root hash changed
!(Arrays.equals(bestBlockRoot, bestBlock.getStateRoot()));
}
if (bestBlockShifted) {
LOG.info("Rebuilding world state SUCCEEDED by REVERTING to a previous block.");
} else {
LOG.info("Rebuilding world state SUCCEEDED.");
}
} else {
LOG.error("Rebuilding world state FAILED. " + "Stop the kernel (Ctrl+C) and use the command line revert option to move back to a valid block. " + "Check the Aion wiki for recommendations on choosing the block number.");
}
countRecoveryAttempts++;
}
// rebuild from genesis if (1) no best block (2) recovery failed
if (bestBlock == null || !recovered) {
if (bestBlock == null) {
LOG.info("DB is empty - adding Genesis");
} else {
LOG.info("DB could not be recovered - adding Genesis");
}
AionGenesis genesis = cfg.getGenesis();
// initialization section for network balance contract
IRepositoryCache track = repository.startTracking();
Address networkBalanceAddress = PrecompiledContracts.totalCurrencyAddress;
track.createAccount(networkBalanceAddress);
for (Map.Entry<Integer, BigInteger> addr : genesis.getNetworkBalances().entrySet()) {
track.addStorageRow(networkBalanceAddress, new DataWord(addr.getKey()), new DataWord(addr.getValue()));
}
for (Address addr : genesis.getPremine().keySet()) {
track.createAccount(addr);
track.addBalance(addr, genesis.getPremine().get(addr).getBalance());
}
track.flush();
repository.commitBlock(genesis.getHeader());
this.repository.getBlockStore().saveBlock(genesis, genesis.getCumulativeDifficulty(), true);
blockchain.setBestBlock(genesis);
blockchain.setTotalDifficulty(genesis.getCumulativeDifficulty());
if (this.eventMgr != null) {
List<IEvent> evts = new ArrayList<>();
evts.add(new EventBlock(EventBlock.CALLBACK.ONBLOCK0));
evts.add(new EventBlock(EventBlock.CALLBACK.ONTRACE0));
this.eventMgr.registerEvent(evts);
} else {
LOG.error("Event manager is null !!!");
System.exit(-1);
}
LOG.info("loaded genesis block <num={}, root={}>", 0, ByteUtil.toHexString(genesis.getStateRoot()));
} else {
blockchain.setBestBlock(bestBlock);
BigInteger totalDifficulty = this.repository.getBlockStore().getTotalDifficulty();
blockchain.setTotalDifficulty(totalDifficulty);
LOG.info("loaded block <num={}, root={}>", blockchain.getBestBlock().getNumber(), LogUtil.toHexF8(blockchain.getBestBlock().getStateRoot()));
}
if (!Arrays.equals(blockchain.getBestBlock().getStateRoot(), EMPTY_TRIE_HASH)) {
this.repository.syncToRoot(blockchain.getBestBlock().getStateRoot());
}
this.repository.getBlockStore().load();
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionBlockStore method getListBlocksEndWithInner.
private List<AionBlock> getListBlocksEndWithInner(byte[] hash, long qty) {
AionBlock block = this.blocks.get(hash);
if (block == null) {
return new ArrayList<>();
}
List<AionBlock> blocks = new ArrayList<>((int) qty);
for (int i = 0; i < qty; ++i) {
blocks.add(block);
block = this.blocks.get(block.getParentHash());
if (block == null) {
break;
}
}
return blocks;
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class AionPoW method processSolution.
/**
* Processes a received solution.
*
* @param solution
* The generated equihash solution
*/
protected synchronized void processSolution(Solution solution) {
if (!shutDown.get()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Best block num [{}]", blockchain.getBestBlock().getNumber());
LOG.debug("Best block nonce [{}]", Hex.toHexString(blockchain.getBestBlock().getNonce()));
LOG.debug("Best block hash [{}]", Hex.toHexString(blockchain.getBestBlock().getHash()));
}
AionBlock block = (AionBlock) solution.getBlock();
if (!Arrays.equals(block.getHeader().getNonce(), new byte[32])) {
// block has been processed
return;
}
// set the nonce and solution
block.getHeader().setNonce(solution.getNonce());
block.getHeader().setSolution(solution.getSolution());
block.getHeader().setTimestamp(solution.getTimeStamp());
// This can be improved
ImportResult importResult = AionImpl.inst().addNewMinedBlock(block);
// Check that the new block was successfully added
if (importResult.isSuccessful()) {
if (importResult == IMPORTED_BEST) {
LOG.info("block sealed <num={}, hash={}, diff={}, tx={}>", block.getNumber(), block.getShortHash(), // LogUtil.toHexF8(newBlock.getHash()),
block.getHeader().getDifficultyBI().toString(), block.getTransactionsList().size());
} else {
LOG.debug("block sealed <num={}, hash={}, diff={}, tx={}, result={}>", block.getNumber(), // LogUtil.toHexF8(newBlock.getHash()),
block.getShortHash(), block.getHeader().getDifficultyBI().toString(), block.getTransactionsList().size(), importResult);
}
// TODO: fire block mined event
} else {
LOG.info("Unable to import a new mined block; restarting mining.\n" + "Mined block import result is " + importResult + " : " + block.getShortHash());
}
}
}
use of org.aion.zero.impl.types.AionBlock in project aion by aionnetwork.
the class BlockPropagationHandler method send.
private boolean send(AionBlock block, int nodeId) {
// current proposal is to send to all peers with lower blockNumbers
AtomicBoolean sent = new AtomicBoolean();
this.p2pManager.getActiveNodes().values().stream().filter(n -> n.getIdHash() != nodeId).filter(n -> n.getBestBlockNumber() <= block.getNumber()).forEach(n -> {
if (log.isDebugEnabled())
log.debug("<sending-new-block hash=" + block.getShortHash() + " to-node=" + n.getIdShort() + ">");
this.p2pManager.send(n.getIdHash(), new BroadcastNewBlock(block));
sent.getAndSet(true);
});
return sent.get();
}
Aggregations