Search in sources :

Example 46 with AionBlock

use of org.aion.zero.impl.types.AionBlock 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 47 with AionBlock

use of org.aion.zero.impl.types.AionBlock 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)

Example 48 with AionBlock

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

the class BlockchainForkingTest method testSameBlockDifferentNonceAndSolutionSimple.

/*-
     * Tests the case where multiple threads submit a single block (content) but
     * with different mining nonces and solutions. In this case our rules dictate
     * that all subsequent blocks are considered invalid.
     *
     *          (common ancestor)
     *          /               \
     *         /                 \
     *        /                   \
     *       (a)o                 (b)x
     *
     * Given:
     * a.td == b.td
     */
@Test
public void testSameBlockDifferentNonceAndSolutionSimple() {
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle b = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = b.bc;
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.emptyList(), true);
    AionBlock sameBlock = new AionBlock(block.getEncoded());
    ImportResult firstRes = bc.tryToConnect(block);
    // check that the returned block is the first block
    assertThat(bc.getBestBlock() == block).isTrue();
    ImportResult secondRes = bc.tryToConnect(sameBlock);
    // the second block should get rejected, so check that the reference still refers
    // to the first block (we dont change the published reference)
    assertThat(bc.getBestBlock() == block).isTrue();
    assertThat(firstRes).isEqualTo(ImportResult.IMPORTED_BEST);
    assertThat(secondRes).isEqualTo(ImportResult.EXIST);
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 49 with AionBlock

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

the class BlockchainIntegrationTest method testAppendIncorrectTimestampBlock.

@Test
public void testAppendIncorrectTimestampBlock() {
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    // set the block to be created 1 month in the future
    block.getHeader().setTimestamp((System.currentTimeMillis() / 1000) + 2592000);
    ImportResult result = bc.tryToConnect(block);
    assertThat(result.isSuccessful()).isFalse();
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 50 with AionBlock

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

the class BlockchainIntegrationTest method testBlockchainDifficultyOnBranching.

@Test
public void testBlockchainDifficultyOnBranching() {
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    BigInteger initialTD = bc.getTotalDifficulty();
    // these two should have different hashes
    AionBlock block1 = bc.createNewBlock(bc.getGenesis(), new ArrayList<>(), true);
    assertThat(bc.tryToConnect(block1)).isEqualTo(ImportResult.IMPORTED_BEST);
    BigInteger postConnectTD = bc.getTotalDifficulty();
    assertThat(postConnectTD).isEqualTo(bc.getGenesis().getDifficultyBI().add(block1.getDifficultyBI()));
    // first scenario is a one level branch, where both branches are of same height
    // but one branch (lighter) comes first, and the second (heavier) comes second
    AionBlock block2 = bc.createNewBlock(block1, new ArrayList<>(), true);
    AionBlock heavyBlock = bc.createNewBlock(block1, new ArrayList<>(), true);
    heavyBlock.getHeader().setDifficulty(BigInteger.valueOf(10000000L).toByteArray());
    assertThat(bc.tryToConnect(block2)).isEqualTo(ImportResult.IMPORTED_BEST);
    BigInteger postBlock2TD = bc.getTotalDifficulty();
    assertThat(postBlock2TD).isEqualTo(postConnectTD.add(block2.getDifficultyBI()));
    assertThat(bc.tryToConnect(heavyBlock)).isEqualTo(ImportResult.IMPORTED_BEST);
    BigInteger postHeavyBlockTD = bc.getTotalDifficulty();
    assertThat(postHeavyBlockTD).isEqualTo(postConnectTD.add(heavyBlock.getDifficultyBI()));
    assertThat(bc.getBlockStore().getBestBlock().getHash()).isEqualTo(heavyBlock.getHash());
    assertThat(bc.getBlockStore().getTotalDifficulty()).isEqualTo(postHeavyBlockTD);
}
Also used : BigInteger(java.math.BigInteger) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Aggregations

AionBlock (org.aion.zero.impl.types.AionBlock)64 Test (org.junit.Test)20 AionTransaction (org.aion.zero.types.AionTransaction)16 BigInteger (java.math.BigInteger)15 ImportResult (org.aion.mcf.core.ImportResult)15 ArrayList (java.util.ArrayList)8 Address (org.aion.base.type.Address)6 ECKey (org.aion.crypto.ECKey)6 AionTxInfo (org.aion.zero.impl.types.AionTxInfo)5 IAionBlock (org.aion.zero.types.IAionBlock)5 JSONObject (org.json.JSONObject)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 ByteArrayWrapper (org.aion.base.util.ByteArrayWrapper)4 StandaloneBlockchain (org.aion.zero.impl.StandaloneBlockchain)4 BlockPropagationHandler (org.aion.zero.impl.sync.handler.BlockPropagationHandler)4 A0BlockHeader (org.aion.zero.types.A0BlockHeader)4 Map (java.util.Map)3 TxRecpt (org.aion.api.server.types.TxRecpt)3 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 LRUMap (org.apache.commons.collections4.map.LRUMap)3