Search in sources :

Example 31 with TrieImpl

use of org.aion.mcf.trie.TrieImpl in project aion by aionnetwork.

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithPartialWorldState.

/**
 * Test the recovery of the world state in the case where it is missing from the database.
 */
@Test
public void testRecoverWorldStateWithPartialWorldState() {
    final int NUMBER_OF_BLOCKS = 10;
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain chain = bundle.bc;
    // first half of blocks will be correct
    ImportResult result;
    for (int i = 0; i < NUMBER_OF_BLOCKS / 2; i++) {
        result = chain.tryToConnect(chain.createNewBlock(chain.getBestBlock(), Collections.emptyList(), true));
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    }
    // second half of blocks will miss the state root
    List<byte[]> statesToDelete = new ArrayList<>();
    for (int i = 0; i < NUMBER_OF_BLOCKS / 2; i++) {
        AionBlock next = chain.createNewBlock(chain.getBestBlock(), Collections.emptyList(), true);
        result = chain.tryToConnect(next);
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
        statesToDelete.add(next.getStateRoot());
    }
    AionBlock bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    // delete some world state root entries from the database
    TrieImpl trie = (TrieImpl) ((AionRepositoryImpl) chain.getRepository()).getWorldState();
    IByteArrayKeyValueDatabase database = (IByteArrayKeyValueDatabase) trie.getCache().getDb();
    for (byte[] key : statesToDelete) {
        database.delete(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(chain.getRepository(), bestBlock.getNumber());
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state is ok
    assertThat(worked).isTrue();
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isTrue();
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) ArrayList(java.util.ArrayList) TrieImpl(org.aion.mcf.trie.TrieImpl) IByteArrayKeyValueDatabase(org.aion.base.db.IByteArrayKeyValueDatabase) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 32 with TrieImpl

use of org.aion.mcf.trie.TrieImpl in project aion by aionnetwork.

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithoutGenesis.

/**
 * Test the recovery of the world state in the case where it is missing from the database.
 */
@Test
public void testRecoverWorldStateWithoutGenesis() {
    final int NUMBER_OF_BLOCKS = 10;
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain chain = bundle.bc;
    // all blocks will be incorrect
    ImportResult result;
    for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
        AionBlock next = chain.createNewBlock(chain.getBestBlock(), Collections.emptyList(), true);
        result = chain.tryToConnect(next);
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    }
    AionBlock bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    // delete some world state root entries from the database
    TrieImpl trie = (TrieImpl) ((AionRepositoryImpl) chain.getRepository()).getWorldState();
    IByteArrayKeyValueDatabase database = (IByteArrayKeyValueDatabase) trie.getCache().getDb();
    List<byte[]> statesToDelete = new ArrayList<>();
    statesToDelete.addAll(database.keys());
    for (byte[] key : statesToDelete) {
        database.delete(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(chain.getRepository(), bestBlock.getNumber());
    // 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();
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) ArrayList(java.util.ArrayList) TrieImpl(org.aion.mcf.trie.TrieImpl) IByteArrayKeyValueDatabase(org.aion.base.db.IByteArrayKeyValueDatabase) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Aggregations

TrieImpl (org.aion.mcf.trie.TrieImpl)32 Test (org.junit.Test)31 Parameters (junitparams.Parameters)5 MockDB (org.aion.db.impl.mockdb.MockDB)5 ArrayList (java.util.ArrayList)3 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 ImportResult (org.aion.mcf.core.ImportResult)3 AionBlock (org.aion.zero.impl.types.AionBlock)3 RLPElement (org.aion.rlp.RLPElement)1 AionTransaction (org.aion.zero.types.AionTransaction)1