Search in sources :

Example 81 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionRepositoryImpl method queryTransaction.

/**
 * @return {@code true} when the operation was successfult and {@code false} otherwise
 */
public boolean queryTransaction(byte[] txHash, Logger log) {
    try {
        Map<ByteArrayWrapper, AionTxInfo> txInfoList = transactionStore.getTxInfo(txHash);
        if (txInfoList == null || txInfoList.isEmpty()) {
            log.error("Can not find the transaction with given hash.");
            return false;
        }
        for (Map.Entry<ByteArrayWrapper, AionTxInfo> entry : txInfoList.entrySet()) {
            Block block = blockStore.getBlockByHash(entry.getKey().toBytes());
            if (block == null) {
                log.error("Cannot find the block data for the block hash from the transaction info. The database might be corrupted. Please consider reimporting the database by running ./aion.sh -n <network> --redo-import");
                return false;
            }
            AionTransaction tx = block.getTransactionsList().get(entry.getValue().getIndex());
            if (tx == null) {
                log.error("Cannot find the transaction data for the given hash. The database might be corrupted. Please consider reimporting the database by running ./aion.sh -n <network> --redo-import");
                return false;
            }
            log.info(tx.toString());
            log.info(entry.getValue().toString());
        }
        return true;
    } catch (Exception e) {
        log.error("Error encountered while attempting to retrieve the transaction data.", e);
        return false;
    }
}
Also used : ByteArrayWrapper(org.aion.util.types.ByteArrayWrapper) AionTxInfo(org.aion.zero.impl.types.AionTxInfo) Block(org.aion.zero.impl.types.Block) AionTransaction(org.aion.base.AionTransaction) Map(java.util.Map) HashMap(java.util.HashMap) IOException(java.io.IOException)

Example 82 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionRepositoryImpl method dumpTestData.

public void dumpTestData(long blockNumber, String[] otherParameters, String basePath, Logger log) {
    try {
        String file = blockStore.dumpPastBlocksForConsensusTest(blockNumber, basePath);
        if (file == null) {
            log.error("Illegal arguments. Cannot print block information.");
        } else {
            log.info("Block information stored in " + file);
        }
    } catch (IOException e) {
        log.error("Exception encountered while writing data to file.", e);
    }
    int paramIndex = 1;
    // print state for parent block
    Block parent = blockStore.getChainBlockByNumber(blockNumber - 1);
    if (parent == null) {
        log.error("Illegal arguments. Parent block is null.");
    } else {
        if (otherParameters.length > paramIndex && otherParameters[paramIndex].equals("skip-state")) {
            log.info("Parent state information is not retrieved.");
            paramIndex++;
        } else {
            try {
                syncToRoot(parent.getStateRoot());
                File file = new File(basePath, System.currentTimeMillis() + "-state-for-parent-block-" + parent.getNumber() + ".out");
                BufferedWriter writer = new BufferedWriter(new FileWriter(file));
                writer.append(Hex.toHexString(dumpImportableState(parent.getStateRoot(), Integer.MAX_VALUE, DatabaseType.STATE)));
                writer.newLine();
                writer.close();
                log.info("Parent state information stored in " + file.getName());
            } catch (IOException e) {
                log.error("Exception encountered while writing data to file.", e);
            }
        }
        // print details and storage for the given contracts
        if (otherParameters.length > paramIndex) {
            try {
                syncToRoot(parent.getStateRoot());
                File file = new File(basePath, System.currentTimeMillis() + "-state-contracts.out");
                BufferedWriter writer = new BufferedWriter(new FileWriter(file));
                // iterate through contracts
                for (int i = paramIndex; i < otherParameters.length; i++) {
                    writer.append("Contract: " + AddressUtils.wrapAddress(otherParameters[i]));
                    writer.newLine();
                    StoredContractDetails details = getContractDetails(AddressUtils.wrapAddress(otherParameters[i]));
                    if (details != null) {
                        writer.append("Details: " + Hex.toHexString(details.getEncoded()));
                        writer.newLine();
                        writer.append("Storage: " + Hex.toHexString(dumpImportableStorage(details.getStorageHash(), Integer.MAX_VALUE, AddressUtils.wrapAddress(otherParameters[i]))));
                        writer.newLine();
                    }
                    writer.newLine();
                }
                writer.close();
                log.info("Contract details and storage information stored in " + file.getName());
            } catch (IOException e) {
                log.error("Exception encountered while writing data to file.", e);
            }
        }
    }
}
Also used : FileWriter(java.io.FileWriter) Block(org.aion.zero.impl.types.Block) Hex.toHexString(org.aion.util.conversions.Hex.toHexString) IOException(java.io.IOException) File(java.io.File) BufferedWriter(java.io.BufferedWriter)

Example 83 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionBlockStore method pruneAndCorrect.

public void pruneAndCorrect(Logger log) {
    lock.lock();
    try {
        Block block = getBestBlockWithInfo();
        if (block == null) {
            log.error("Can't find the best block. PruneAndCorrect failed!");
            log.error("Please reboot your node to trigger automatic database recovery by the kernel.");
            throw new IllegalStateException("Missing the best block from the database.");
        }
        long initialLevel = block.getNumber();
        long level = initialLevel;
        long start = System.nanoTime();
        final long TEN_SEC = 10_000_000_000L;
        // top down pruning of nodes on side chains
        while (level > 0) {
            if (System.nanoTime() - start > TEN_SEC) {
                log.info("Progress report: pruning side chains on level " + level + ".");
                start = System.nanoTime();
            }
            pruneSideChains(block, log);
            block = blocks.get(block.getParentHash());
            if (block == null) {
                log.error("Block #" + (level - 1) + " missing from the database. " + "Cannot proceed with block pruning and total difficulty updates.");
                log.error(" Please shutdown the kernel and rollback the database by executing:\t./aion.sh -n <network> -r {}", level - 1);
                throw new IllegalStateException("Missing block from the database.");
            }
            level = block.getNumber();
        }
        // prune genesis
        pruneSideChains(block, log);
        // bottom up repair of information
        // initial TD set to genesis TD
        level = 1;
        while (level <= initialLevel) {
            BigInteger totalDifficulty = correctTotalDifficulty(level, block.getTotalDifficulty(), log);
            if (totalDifficulty == null) {
                log.error("CorrectTotalDifficulty failed! level:{}", level);
                throw new IllegalStateException("The Index database might corrupt!");
            }
            log.info("Updated difficulties on level " + level + " to " + " total difficulty: " + totalDifficulty + ".");
            level++;
        }
    } finally {
        lock.unlock();
    }
}
Also used : Block(org.aion.zero.impl.types.Block) BigInteger(java.math.BigInteger)

Example 84 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionBlockStore method dumpPastBlocksForConsensusTest.

String dumpPastBlocksForConsensusTest(long firstBlock, String reportsFolder) throws IOException {
    lock.lock();
    try {
        if (firstBlock < 0) {
            return null;
        }
        // the 1st block will be imported by the test
        // its total difficulty, state root and receipt hash can be used for validation
        // the 2nd block will be used to setup the blockchain world state before import
        // the 3rd block is also part of the setup as it is required for header validation
        long lastBlock = firstBlock - 3;
        File file = new File(reportsFolder, System.currentTimeMillis() + "-blocks-for-consensus-test.out");
        BufferedWriter writer = new BufferedWriter(new FileWriter(file));
        while (firstBlock > lastBlock && firstBlock >= 0) {
            List<BlockInfo> levelBlocks = getBlockInfoForLevel(firstBlock);
            for (BlockInfo bi : levelBlocks) {
                if (bi.isMainChain()) {
                    writer.append("\nBlock hash from index database: " + Hex.toHexString(bi.getHash()) + "\nTotal Difficulty: " + bi.getTotalDifficulty() + "\nBlock on main chain: " + String.valueOf(bi.isMainChain()).toUpperCase());
                    writer.newLine();
                    Block blk = blocks.get(bi.getHash());
                    if (blk != null) {
                        writer.append("\nFull block data:\n");
                        writer.append(blk.toString());
                        writer.newLine();
                    } else {
                        writer.append("Retrieved block data is null.");
                    }
                }
            }
            writer.newLine();
            firstBlock--;
        }
        writer.close();
        return file.getName();
    } finally {
        lock.unlock();
    }
}
Also used : FileWriter(java.io.FileWriter) Block(org.aion.zero.impl.types.Block) File(java.io.File) BufferedWriter(java.io.BufferedWriter)

Example 85 with Block

use of org.aion.zero.impl.types.Block in project aion by aionnetwork.

the class AionBlockStore method revert.

/**
 * Reverts the blockchain to the given height.
 *
 * @param targetLevel the height of the blockchain that we must revert to
 */
public void revert(long targetLevel, Logger log) {
    lock.lock();
    try {
        log.info("Block store revert STARTED.");
        Block bestBlock = getBestBlock();
        if (bestBlock == null) {
            log.error("Can't find the best block. Revert FAILED!" + "Please reboot your node to trigger automatic database recovery by the kernel.");
            throw new IllegalStateException("Missing the best block from the database.");
        }
        long currentLevel = bestBlock.getNumber();
        final long TARGET_BATCH_SIZE = 1_000, TEN_SEC = 10_000_000_000L;
        long currentBatchSize = 0;
        long time = System.nanoTime();
        // ensure that the given level is lower than current
        if (targetLevel >= currentLevel) {
            return;
        }
        // walk back removing blocks greater than the given level value
        while (currentLevel > targetLevel) {
            // remove all the blocks at that level
            List<BlockInfo> currentLevelBlocks = getBlockInfoForLevel(currentLevel);
            if (currentLevelBlocks == null || currentLevelBlocks.isEmpty()) {
                log.error("Null block information found at " + currentLevel + " when information should exist." + "Please reboot your node to trigger automatic database recovery by the kernel.");
            } else {
                for (BlockInfo bk_info : currentLevelBlocks) {
                    blocks.delete(bk_info.getHash());
                    currentBatchSize++;
                }
            }
            // remove the level
            index.remove(currentLevel);
            if (currentBatchSize >= TARGET_BATCH_SIZE) {
                blocks.commit();
                if (System.nanoTime() - time > TEN_SEC) {
                    log.info("Progress report: current height=" + currentLevel);
                    time = System.nanoTime();
                }
                currentBatchSize = 0;
            }
            --currentLevel;
        }
        blocks.commit();
        log.info("Block store revert COMPLETE.");
        log.warn("Please be aware that the current main chain is the same chain that contained the best block encountered at the start of this operation. " + "To keep this revert operation fast the main chain has not been updated based on existing side chains. The main chain will adjust itself when new blocks are imported.");
    } catch (Exception e) {
        // making sure the blocks get deleted if interrupted
        blocks.commit();
    } finally {
        lock.unlock();
    }
}
Also used : Block(org.aion.zero.impl.types.Block) IOException(java.io.IOException)

Aggregations

Block (org.aion.zero.impl.types.Block)283 MiningBlock (org.aion.zero.impl.types.MiningBlock)155 Test (org.junit.Test)148 AionTransaction (org.aion.base.AionTransaction)106 ImportResult (org.aion.zero.impl.core.ImportResult)86 ArrayList (java.util.ArrayList)63 AionAddress (org.aion.types.AionAddress)61 StakingBlock (org.aion.zero.impl.types.StakingBlock)58 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)57 BigInteger (java.math.BigInteger)55 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)34 ByteArrayWrapper (org.aion.util.types.ByteArrayWrapper)30 AionTxReceipt (org.aion.base.AionTxReceipt)29 Hex.toHexString (org.aion.util.conversions.Hex.toHexString)28 AccountState (org.aion.base.AccountState)26 EventBlock (org.aion.evtmgr.impl.evt.EventBlock)26 JSONArray (org.json.JSONArray)26 JSONObject (org.json.JSONObject)26 MiningBlockHeader (org.aion.zero.impl.types.MiningBlockHeader)22 AionTxExecSummary (org.aion.base.AionTxExecSummary)20