Search in sources :

Example 76 with Block

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

the class BlockchainDataRecoveryTest method testRecoverWorldState_wDeletedBlock.

@Test
public void testRecoverWorldState_wDeletedBlock() {
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).build();
    StandaloneBlockchain chain = bundle.bc;
    AionRepositoryImpl repo = chain.getRepository();
    BlockContext context;
    List<AionTransaction> txs;
    // all blocks will be incorrect
    long time = System.currentTimeMillis();
    List<byte[]> statesToDelete = new ArrayList<>();
    List<MiningBlock> blocksToImport = new ArrayList<>();
    for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
        txs = BlockchainTestUtils.generateTransactions(MAX_TX_PER_BLOCK, accounts, repo);
        context = chain.createNewMiningBlockInternal(chain.getBestBlock(), txs, true, time / 10000L);
        assertThat(chain.tryToConnect(context.block)).isEqualTo(ImportResult.IMPORTED_BEST);
        statesToDelete.add(context.block.getStateRoot());
        // skipping middle block
        if (context.block.getNumber() != NUMBER_OF_BLOCKS / 2) {
            blocksToImport.add(context.block);
        }
    }
    Block bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    // delete middle block from db
    Block middle = chain.getBlockByNumber(NUMBER_OF_BLOCKS / 2);
    MockDB database = (MockDB) repo.getBlockDatabase();
    database.deleteAndCommit(middle.getHash());
    // delete some world state root entries from the database
    TrieImpl trie = (TrieImpl) repo.getWorldState();
    database = (MockDB) repo.getStateDatabase();
    // 1: direct recovery call
    repo.flush();
    for (byte[] key : statesToDelete) {
        database.deleteAndCommit(key);
        assertThat(trie.isValidRoot(key)).isFalse();
    }
    // ensure that the world state was corrupted
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // call the recovery functionality
    assertThat(chain.recoverWorldState(repo, bestBlock)).isFalse();
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state could not be recovered
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // 2: recovery at import
    repo.flush();
    for (byte[] key : statesToDelete) {
        database.deleteAndCommit(key);
        assertThat(trie.isValidRoot(key)).isFalse();
    }
    // ensure that the world state was corrupted
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // call the recovery functionality indirectly
    for (MiningBlock block : blocksToImport) {
        // state missing before import
        assertThat(trie.isValidRoot(block.getStateRoot())).isFalse();
        assertThat(chain.tryToConnect(block)).isEqualTo(ImportResult.EXIST);
        if (block.getNumber() < middle.getNumber()) {
            // state present after import
            assertThat(trie.isValidRoot(block.getStateRoot())).isTrue();
        } else {
            // block after missing one cannot be recovered
            assertThat(trie.isValidRoot(block.getStateRoot())).isFalse();
        }
    }
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state is ok
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // importing middle block
    assertThat(chain.tryToConnect(middle)).isEqualTo(ImportResult.IMPORTED_NOT_BEST);
    // call the recovery functionality indirectly
    for (MiningBlock block : blocksToImport) {
        // checking only failed blocks from before
        if (block.getNumber() > middle.getNumber()) {
            // state missing before import
            assertThat(trie.isValidRoot(block.getStateRoot())).isFalse();
            assertThat(chain.tryToConnect(block)).isEqualTo(ImportResult.EXIST);
            // state present after import
            assertThat(trie.isValidRoot(block.getStateRoot())).isTrue();
        }
    }
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state is ok
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isTrue();
}
Also used : BlockContext(org.aion.zero.impl.types.BlockContext) MockDB(org.aion.db.impl.mockdb.MockDB) ArrayList(java.util.ArrayList) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) TrieImpl(org.aion.zero.impl.trie.TrieImpl) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) Test(org.junit.Test)

Example 77 with Block

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

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithoutGenesis.

/**
 * Test the recovery of the world state when missing the genesis block state.
 *
 * <p>Under these circumstances the recovery will fail.
 */
@Test
public void testRecoverWorldStateWithoutGenesis() {
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).build();
    StandaloneBlockchain chain = bundle.bc;
    AionRepositoryImpl repo = chain.getRepository();
    BlockContext context;
    List<AionTransaction> txs;
    // all blocks will be incorrect
    long time = System.currentTimeMillis();
    List<MiningBlock> blocksToImport = new ArrayList<>();
    for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
        txs = BlockchainTestUtils.generateTransactions(MAX_TX_PER_BLOCK, accounts, repo);
        context = chain.createNewMiningBlockInternal(chain.getBestBlock(), txs, true, time / 10000L);
        assertThat(chain.tryToConnect(context.block)).isEqualTo(ImportResult.IMPORTED_BEST);
        blocksToImport.add(context.block);
    }
    Block bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    // delete some world state root entries from the database
    TrieImpl trie = (TrieImpl) repo.getWorldState();
    MockDB database = (MockDB) repo.getStateDatabase();
    // 1: direct recovery call
    repo.flush();
    List<byte[]> statesToDelete = new ArrayList<>();
    Iterator<byte[]> iterator = database.keys();
    while (iterator.hasNext()) {
        statesToDelete.add(iterator.next());
    }
    for (byte[] key : statesToDelete) {
        database.deleteAndCommit(key);
        assertThat(trie.isValidRoot(key)).isFalse();
    }
    // ensure that the world state was corrupted
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // call the recovery functionality
    boolean worked = chain.recoverWorldState(repo, bestBlock);
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state was not recovered
    assertThat(worked).isFalse();
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // 2: recovery at import
    repo.flush();
    for (byte[] key : statesToDelete) {
        database.deleteAndCommit(key);
        assertThat(trie.isValidRoot(key)).isFalse();
    }
    // ensure that the world state was corrupted
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
    // call the recovery functionality indirectly
    for (MiningBlock block : blocksToImport) {
        // state missing before import
        assertThat(trie.isValidRoot(block.getStateRoot())).isFalse();
        assertThat(chain.tryToConnect(block)).isEqualTo(ImportResult.EXIST);
        // state missing after import (because there is not genesis to recover from)
        assertThat(trie.isValidRoot(block.getStateRoot())).isFalse();
    }
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state is ok
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
}
Also used : BlockContext(org.aion.zero.impl.types.BlockContext) MockDB(org.aion.db.impl.mockdb.MockDB) ArrayList(java.util.ArrayList) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) TrieImpl(org.aion.zero.impl.trie.TrieImpl) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) Test(org.junit.Test)

Example 78 with Block

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

the class ApiAion0Test method testProcessGetTxByBlockHashAndIndex.

@Test
@Ignore
public void testProcessGetTxByBlockHashAndIndex() throws Exception {
    AionImpl impl = AionImpl.instForTest();
    AionRepositoryImpl repo = AionRepositoryImpl.inst();
    Block parentBlk = impl.getBlockchain().getBestBlock();
    AionTransaction tx = AionTransaction.create(key, repo.getNonce(AddressUtils.ZERO_ADDRESS).toByteArray(), AddressUtils.ZERO_ADDRESS, BigInteger.ONE.toByteArray(), msg, 100000, 100000, TransactionTypes.DEFAULT, null);
    Block blk = impl.getAionHub().getBlockchain().createNewMiningBlock(parentBlk, Collections.singletonList(tx), false);
    impl.getAionHub().getBlockchain().tryToConnect(blk);
    Message.req_getTransactionByBlockHashAndIndex reqBody = Message.req_getTransactionByBlockHashAndIndex.newBuilder().setBlockHash(ByteString.copyFrom(blk.getHash())).setTxIndex(0).build();
    rsp = sendRequest(Message.Servs.s_chain_VALUE, Message.Funcs.f_getTransactionByBlockHashAndIndex_VALUE, reqBody.toByteArray());
    assertEquals(Message.Retcode.r_success_VALUE, rsp[1]);
    Message.rsp_getTransaction rslt = Message.rsp_getTransaction.parseFrom(stripHeader(rsp));
    assertEquals(blk.getNumber(), rslt.getBlocknumber());
    assertEquals(ByteString.copyFrom(tx.getData()), rslt.getData());
    assertEquals(tx.getEnergyPrice(), rslt.getNrgPrice());
    rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_getTransactionByBlockHashAndIndex_VALUE);
    assertEquals(Message.Retcode.r_fail_service_call_VALUE, rsp[1]);
}
Also used : AionImpl(org.aion.zero.impl.blockchain.AionImpl) Block(org.aion.zero.impl.types.Block) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionTransaction(org.aion.base.AionTransaction) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 79 with Block

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

the class ApiAion0Test method testProcessGetTxByBlockNumberAndIndex.

@Test
@Ignore
public void testProcessGetTxByBlockNumberAndIndex() throws Exception {
    AionImpl impl = AionImpl.instForTest();
    AionRepositoryImpl repo = AionRepositoryImpl.inst();
    Block parentBlk = impl.getBlockchain().getBestBlock();
    AionTransaction tx = AionTransaction.create(key, repo.getNonce(AddressUtils.ZERO_ADDRESS).toByteArray(), AddressUtils.ZERO_ADDRESS, BigInteger.ONE.toByteArray(), msg, 100000, 100000, TransactionTypes.DEFAULT, null);
    Block blk = impl.getAionHub().getBlockchain().createNewMiningBlock(parentBlk, Collections.singletonList(tx), false);
    impl.getAionHub().getBlockchain().tryToConnect(blk);
    Message.req_getTransactionByBlockNumberAndIndex reqBody = Message.req_getTransactionByBlockNumberAndIndex.newBuilder().setBlockNumber(blk.getNumber()).setTxIndex(0).build();
    rsp = sendRequest(Message.Servs.s_chain_VALUE, Message.Funcs.f_getTransactionByBlockNumberAndIndex_VALUE, reqBody.toByteArray());
    assertEquals(Message.Retcode.r_success_VALUE, rsp[1]);
    Message.rsp_getTransaction rslt = Message.rsp_getTransaction.parseFrom(stripHeader(rsp));
    assertEquals(blk.getNumber(), rslt.getBlocknumber());
    assertEquals(ByteString.copyFrom(tx.getData()), rslt.getData());
    assertEquals(tx.getEnergyPrice(), rslt.getNrgPrice());
    rsp = sendRequest(Message.Servs.s_hb_VALUE, Message.Funcs.f_getTransactionByBlockNumberAndIndex_VALUE);
    assertEquals(Message.Retcode.r_fail_service_call_VALUE, rsp[1]);
}
Also used : AionImpl(org.aion.zero.impl.blockchain.AionImpl) Block(org.aion.zero.impl.types.Block) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionTransaction(org.aion.base.AionTransaction) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 80 with Block

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

the class AionRepositoryImpl method printStateTrieDump.

public void printStateTrieDump(long blockNumber, Logger log) {
    Block block;
    if (blockNumber == -1L) {
        block = blockStore.getBestBlock();
        if (block == null) {
            log.error("The requested block does not exist in the database.");
            return;
        }
        blockNumber = block.getNumber();
    } else {
        block = blockStore.getChainBlockByNumber(blockNumber);
        if (block == null) {
            log.error("The requested block does not exist in the database.");
            return;
        }
    }
    byte[] stateRoot = block.getStateRoot();
    log.info("\nBlock hash: " + block.getShortHash() + ", number: " + blockNumber + ", tx count: " + block.getTransactionsList().size() + "\n\n" + getWorldState().getTrieDump(stateRoot));
}
Also used : Block(org.aion.zero.impl.types.Block)

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