use of org.aion.evtmgr.impl.evt.EventBlock 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.evtmgr.impl.evt.EventBlock in project aion by aionnetwork.
the class AionPendingStateImpl method regBlockEvents.
private void regBlockEvents() {
List<IEvent> evts = new ArrayList<>();
evts.add(new EventBlock(EventBlock.CALLBACK.ONBLOCK0));
evts.add(new EventBlock(EventBlock.CALLBACK.ONBEST0));
this.evtMgr.registerEvent(evts);
}
use of org.aion.evtmgr.impl.evt.EventBlock in project aion by aionnetwork.
the class AionBlockchainImpl method tryToConnect.
public synchronized ImportResult tryToConnect(final AionBlock block) {
long currentTimestamp = System.currentTimeMillis() / THOUSAND_MS;
if (block.getTimestamp() > (currentTimestamp + this.chainConfiguration.getConstants().getClockDriftBufferTime()))
return INVALID_BLOCK;
if (LOG.isDebugEnabled()) {
LOG.debug("Try connect block hash: {}, number: {}", Hex.toHexString(block.getHash()).substring(0, 6), block.getNumber());
}
if (getBlockStore().getMaxNumber() >= block.getNumber() && getBlockStore().isBlockExist(block.getHash())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Block already exist hash: {}, number: {}", Hex.toHexString(block.getHash()).substring(0, 6), block.getNumber());
}
// retry of well known block
return EXIST;
}
final ImportResult ret;
// The simple case got the block
// to connect to the main chain
final AionBlockSummary summary;
if (bestBlock.isParentOf(block)) {
summary = add(block);
ret = summary == null ? INVALID_BLOCK : IMPORTED_BEST;
} else {
if (getBlockStore().isBlockExist(block.getParentHash())) {
BigInteger oldTotalDiff = getTotalDifficulty();
summary = tryConnectAndFork(block);
ret = summary == null ? INVALID_BLOCK : (isMoreThan(getTotalDifficulty(), oldTotalDiff) ? IMPORTED_BEST : IMPORTED_NOT_BEST);
} else {
summary = null;
ret = NO_PARENT;
}
}
if (ret.isSuccessful()) {
if (this.evtMgr != null) {
IEvent evtOnBlock = new EventBlock(EventBlock.CALLBACK.ONBLOCK0);
evtOnBlock.setFuncArgs(Collections.singletonList(summary));
this.evtMgr.newEvent(evtOnBlock);
IEvent evtTrace = new EventBlock(EventBlock.CALLBACK.ONTRACE0);
String str = String.format("Block chain size: [ %d ]", this.getSizeInternal());
evtTrace.setFuncArgs(Collections.singletonList(str));
this.evtMgr.newEvent(evtTrace);
if (ret == IMPORTED_BEST) {
if (LOG.isTraceEnabled()) {
LOG.trace("IMPORTED_BEST");
}
IEvent evtOnBest = new EventBlock(EventBlock.CALLBACK.ONBEST0);
evtOnBest.setFuncArgs(Arrays.asList(block, summary.getReceipts()));
this.evtMgr.newEvent(evtOnBest);
}
}
}
return ret;
}
Aggregations