Search in sources :

Example 41 with ImportResult

use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.

the class BlockchainIndexIntegrityTest method testIndexIntegrityWithoutLevel.

/**
 * Test the index integrity check and recovery when the index database is missing a level
 * information.
 *
 * <p>Under these circumstances the recovery process will fail.
 */
@Test
public void testIndexIntegrityWithoutLevel() {
    final int NUMBER_OF_BLOCKS = 5;
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain chain = bundle.bc;
    ImportResult result;
    for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
        Block next = chain.createNewMiningBlock(chain.getBestBlock(), Collections.emptyList(), true);
        result = chain.tryToConnect(next);
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    }
    Block bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    AionRepositoryImpl repo = chain.getRepository();
    MockDB indexDatabase = (MockDB) repo.getIndexDatabase();
    // deleting the level 2 index
    indexDatabase.deleteAndCommit(ByteUtil.intToBytes(2));
    AionBlockStore blockStore = repo.getBlockStore();
    // check that the index recovery failed
    assertThat(blockStore.indexIntegrityCheck()).isEqualTo(AionBlockStore.IntegrityCheckResult.MISSING_LEVEL);
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) MockDB(org.aion.db.impl.mockdb.MockDB) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionBlockStore(org.aion.zero.impl.db.AionBlockStore) Test(org.junit.Test)

Example 42 with ImportResult

use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.

the class BlockchainIndexIntegrityTest method testIndexIntegrityWithCorrectData.

/**
 * Test the index integrity check and recovery when the index database is correct.
 */
@Test
public void testIndexIntegrityWithCorrectData() {
    final int NUMBER_OF_BLOCKS = 5;
    // build a blockchain with a few blocks
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain chain = bundle.bc;
    Block bestBlock;
    ImportResult result;
    for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
        bestBlock = chain.getBestBlock();
        MiningBlock next = chain.createNewMiningBlock(bestBlock, Collections.emptyList(), true);
        result = chain.tryToConnect(next);
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
        // adding side chain
        next = chain.createNewMiningBlock(bestBlock, Collections.emptyList(), true);
        MiningBlockHeader newBlockHeader = MiningBlockHeader.Builder.newInstance().withHeader(next.getHeader()).withExtraData("other".getBytes()).build();
        next.updateHeader(newBlockHeader);
        result = chain.tryToConnect(next);
        assertThat(result).isEqualTo(ImportResult.IMPORTED_NOT_BEST);
    }
    bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    AionRepositoryImpl repo = chain.getRepository();
    AionBlockStore blockStore = repo.getBlockStore();
    // check that the index recovery succeeded
    assertThat(blockStore.indexIntegrityCheck()).isEqualTo(AionBlockStore.IntegrityCheckResult.CORRECT);
}
Also used : MiningBlockHeader(org.aion.zero.impl.types.MiningBlockHeader) ImportResult(org.aion.zero.impl.core.ImportResult) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionBlockStore(org.aion.zero.impl.db.AionBlockStore) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 43 with ImportResult

use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.

the class BlockchainPruningTest method testTopPruningWithoutSideChains.

@Test
public void testTopPruningWithoutSideChains() throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException {
    // Setup used accounts.
    assertThat(accounts.size()).isAtLeast(12);
    ECKey stakingRegistryOwner = accounts.get(0);
    // Lists of stakers.
    List<ECKey> allStakes = List.of(accounts.get(1), accounts.get(2), accounts.get(3), accounts.get(4), accounts.get(5), accounts.get(6));
    List<ECKey> mainStakers = List.of(accounts.get(1), accounts.get(2), accounts.get(3));
    List<ECKey> otherStakers = List.of(accounts.get(4), accounts.get(5), accounts.get(6));
    // Lists of users.
    List<ECKey> mainUsers = List.of(accounts.get(1), accounts.get(2), accounts.get(3), accounts.get(7), accounts.get(8), accounts.get(9));
    List<ECKey> otherUsers = List.of(accounts.get(4), accounts.get(5), accounts.get(6), accounts.get(10), accounts.get(11), accounts.get(0));
    // Setup the blockchain.
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain chain = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
    chain.forkUtility.enableUnityFork(unityForkBlock);
    // Setup TOP pruning for the repository.
    AionRepositoryImpl repository = chain.getRepository();
    repository.setupTopPruning(1);
    // Setup the first block in the chain with the staker registry deployment.
    Block nextBlock = BlockchainTestUtils.generateNextMiningBlockWithStakerRegistry(chain, chain.getGenesis(), resourceProvider, stakingRegistryOwner);
    Pair<ImportResult, AionBlockSummary> result = chain.tryToConnectAndFetchSummary(nextBlock);
    assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
    assertThat(result.getRight().getReceipts().get(0).isSuccessful()).isTrue();
    assertThat(result.getRight().getReceipts().get(0).getLogInfoList()).isNotEmpty();
    assertThat(result.getRight().getReceipts().get(0).getEnergyUsed()).isEqualTo(1_225_655L);
    // Ensure the current state was not pruned after the import.
    verifyFullState(repository, nextBlock);
    // Set the staking contract address in the staking genesis.
    AionTransaction deploy = nextBlock.getTransactionsList().get(0);
    AionAddress contract = TxUtil.calculateContractAddress(deploy.getSenderAddress().toByteArray(), deploy.getNonceBI());
    chain.getGenesis().setStakingContractAddress(contract);
    // Create block to register all stakers.
    nextBlock = BlockchainTestUtils.generateNextMiningBlockWithStakers(chain, chain.getBestBlock(), resourceProvider, allStakes, MIN_SELF_STAKE);
    result = chain.tryToConnectAndFetchSummary(nextBlock);
    assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
    // Ensure the current state was not pruned after the import.
    verifyFullState(repository, nextBlock);
    // Verify that all stakers were registered.
    verifyReceipts(result.getRight().getReceipts(), allStakes.size(), true);
    verifyEffectiveSelfStake(otherStakers, chain, nextBlock, MIN_SELF_STAKE);
    // Generate random transactions for all accounts to add them to the state.
    List<AionTransaction> txs = BlockchainTestUtils.generateTransactions(1_000, accounts, chain.getRepository());
    nextBlock = BlockchainTestUtils.generateNextStakingBlock(chain, nextBlock, txs, otherStakers.get(0));
    result = chain.tryToConnectAndFetchSummary(nextBlock);
    assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
    // Ensure the current state was not pruned after the import.
    verifyFullState(repository, nextBlock);
    BigInteger expectedStake = MIN_SELF_STAKE;
    for (int i = 0; i < 6; i++) {
        // Add blocks with transactions for mainStakers and mainUsers.
        for (int j = 0; j < 6; j++) {
            // Add transactions for frequent users.
            txs = BlockchainTestUtils.generateTransactions(1_000, mainUsers, chain.getRepository());
            // Seal the block with a frequent staker.
            ECKey staker = mainStakers.get((i + j) % mainStakers.size());
            if (nextBlock instanceof MiningBlock) {
                nextBlock = BlockchainTestUtils.generateNextStakingBlock(chain, nextBlock, txs, staker);
            } else {
                nextBlock = BlockchainTestUtils.generateNextMiningBlock(chain, nextBlock, txs);
            }
            result = chain.tryToConnectAndFetchSummary(nextBlock);
            assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
            // Ensure the current state was not pruned after the import.
            verifyFullState(repository, nextBlock);
        }
        // Increase stake of mainStakes.
        txs = BlockchainTestUtils.generateIncreaseStakeTransactions(chain, nextBlock, resourceProvider, mainStakers, MIN_SELF_STAKE);
        assertThat(txs.size()).isEqualTo(mainStakers.size());
        nextBlock = BlockchainTestUtils.generateNextMiningBlock(chain, nextBlock, txs);
        result = chain.tryToConnectAndFetchSummary(nextBlock);
        assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
        verifyReceipts(result.getRight().getReceipts(), mainStakers.size(), false);
        // Ensure the current state was not pruned after the import.
        verifyFullState(repository, nextBlock);
        // Verify stakers effective stake update.
        expectedStake = expectedStake.add(MIN_SELF_STAKE);
        verifyEffectiveSelfStake(mainStakers, chain, nextBlock, expectedStake);
        // Add transactions for infrequent users.
        txs = BlockchainTestUtils.generateTransactions(10, otherUsers, chain.getRepository());
        // Seal the block with an infrequent staker.
        ECKey staker = otherStakers.get(i % otherStakers.size());
        nextBlock = BlockchainTestUtils.generateNextStakingBlock(chain, nextBlock, txs, staker);
        result = chain.tryToConnectAndFetchSummary(nextBlock);
        assertThat(result.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
        // Ensure the current state was not pruned after the import.
        verifyFullState(repository, nextBlock);
    }
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) AionAddress(org.aion.types.AionAddress) ECKey(org.aion.crypto.ECKey) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Example 44 with ImportResult

use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.

the class BlockchainTestUtils method addStakingBlock.

public static Pair<Block, ImportResult> addStakingBlock(StandaloneBlockchain chain, Block parent, List<AionTransaction> txs, ECKey key) {
    byte[] parentSeed = chain.forkUtility.isUnityForkBlock(parent.getNumber()) ? StakingBlockHeader.GENESIS_SEED : ((StakingBlock) chain.getBlockByHash(parent.getParentHash())).getSeed();
    byte[] newSeed = key.sign(parentSeed).getSignature();
    StakingBlock block = chain.createStakingBlockTemplate(parent, txs, key.getPubKey(), newSeed, new AionAddress(key.getAddress()).toByteArray());
    if (block == null) {
        return null;
    }
    byte[] mineHashSig = key.sign(block.getHeader().getMineHash()).getSignature();
    block.seal(mineHashSig, key.getPubKey());
    ImportResult result = chain.tryToConnect(block);
    System.out.format("Created block with hash: %s, number: %6d, extra data: %6s, txs: %3d, import status: %20s %n", block.getShortHash(), block.getNumber(), new String(block.getExtraData()), block.getTransactionsList().size(), result.toString());
    return Pair.of(block, result);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) StakingBlock(org.aion.zero.impl.types.StakingBlock)

Example 45 with ImportResult

use of org.aion.zero.impl.core.ImportResult in project aion by aionnetwork.

the class AionBlockchainImplTest method testBlockTemplateClearWhenChainBranched.

@Test
public /**
 * we only test the mining block template has been cleared. The method call in the AionBlockchainImpl
 * also proved the staking block template will be cleaned at the same time.
 */
void testBlockTemplateClearWhenChainBranched() {
    CfgAion cfg = CfgAion.inst();
    Properties p = new Properties();
    p.put("fork1.0", "4");
    cfg.getFork().setProtocolUpgradeSettings(p, null);
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withDefaultAccounts().withValidatorConfiguration("simple").build();
    this.blockchain = bundle.bc;
    assertNotNull(blockchain);
    MiningBlock block1a = blockchain.createBlockAndBlockTemplate(blockchain.genesis, new ArrayList<>(), false, blockchain.genesis.getTimestamp() + 10);
    Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block1a);
    assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft());
    assertEquals(1, blockchain.miningBlockTemplate.size());
    MiningBlock block2a = blockchain.createBlockAndBlockTemplate(blockchain.getBestBlock(), new ArrayList<>(), false, blockchain.getBestBlock().getTimestamp() + 1000);
    connectResult = blockchain.tryToConnectAndFetchSummary(block2a);
    assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft());
    assertEquals(2, blockchain.miningBlockTemplate.size());
    // create a side chain block 2b first
    MiningBlock block2b = blockchain.createBlockAndBlockTemplate(block1a, new ArrayList<>(), false, block1a.getTimestamp() + 1);
    connectResult = blockchain.tryToConnectAndFetchSummary(block2b);
    assertEquals(ImportResult.IMPORTED_NOT_BEST, connectResult.getLeft());
    assertEquals(3, blockchain.miningBlockTemplate.size());
    MiningBlock block3a = blockchain.createBlockAndBlockTemplate(blockchain.getBestBlock(), new ArrayList<>(), false, block2a.getTimestamp() + 10);
    connectResult = blockchain.tryToConnectAndFetchSummary(block3a);
    assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft());
    assertEquals(3, blockchain.miningBlockTemplate.size());
    // Chain will be branched after import the block3b and the template will be cleaned.
    MiningBlock block3b = blockchain.createBlockAndBlockTemplate(block2b, new ArrayList<>(), false, block2b.getTimestamp() + 1);
    connectResult = blockchain.tryToConnectAndFetchSummary(block3b);
    assertEquals(ImportResult.IMPORTED_BEST, connectResult.getLeft());
    assertEquals(0, blockchain.miningBlockTemplate.size());
}
Also used : CfgAion(org.aion.zero.impl.config.CfgAion) ImportResult(org.aion.zero.impl.core.ImportResult) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) Properties(java.util.Properties) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Aggregations

ImportResult (org.aion.zero.impl.core.ImportResult)166 Test (org.junit.Test)127 AionTransaction (org.aion.base.AionTransaction)114 AionAddress (org.aion.types.AionAddress)106 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)95 MiningBlock (org.aion.zero.impl.types.MiningBlock)90 Block (org.aion.zero.impl.types.Block)80 BigInteger (java.math.BigInteger)75 AionTxReceipt (org.aion.base.AionTxReceipt)50 AionTxExecSummary (org.aion.base.AionTxExecSummary)31 ECKey (org.aion.crypto.ECKey)28 RepositoryCache (org.aion.base.db.RepositoryCache)22 StandaloneBlockchain (org.aion.zero.impl.blockchain.StandaloneBlockchain)22 InternalTransaction (org.aion.types.InternalTransaction)20 AccountState (org.aion.base.AccountState)18 ArrayList (java.util.ArrayList)17 AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock (org.aion.zero.impl.blockchain.AionBlockchainImpl.getPostExecutionWorkForGeneratePreBlock)16 Builder (org.aion.zero.impl.blockchain.StandaloneBlockchain.Builder)14 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)10 BlockContext (org.aion.zero.impl.types.BlockContext)9