Search in sources :

Example 1 with EventBlock

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();
}
Also used : Address(org.aion.base.type.Address) IEvent(org.aion.evtmgr.IEvent) DataWord(org.aion.mcf.vm.types.DataWord) BigInteger(java.math.BigInteger) EventBlock(org.aion.evtmgr.impl.evt.EventBlock) IRepositoryCache(org.aion.base.db.IRepositoryCache) BigInteger(java.math.BigInteger) AionBlock(org.aion.zero.impl.types.AionBlock)

Example 2 with EventBlock

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);
}
Also used : EventBlock(org.aion.evtmgr.impl.evt.EventBlock) IEvent(org.aion.evtmgr.IEvent)

Example 3 with EventBlock

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;
}
Also used : EventBlock(org.aion.evtmgr.impl.evt.EventBlock) ImportResult(org.aion.mcf.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) IEvent(org.aion.evtmgr.IEvent) BigInteger(java.math.BigInteger)

Aggregations

IEvent (org.aion.evtmgr.IEvent)3 EventBlock (org.aion.evtmgr.impl.evt.EventBlock)3 BigInteger (java.math.BigInteger)2 IRepositoryCache (org.aion.base.db.IRepositoryCache)1 Address (org.aion.base.type.Address)1 ImportResult (org.aion.mcf.core.ImportResult)1 DataWord (org.aion.mcf.vm.types.DataWord)1 AionBlock (org.aion.zero.impl.types.AionBlock)1 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)1