Search in sources :

Example 61 with MiningBlock

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

the class BlockchainConcurrentImportTest method generateBlocks.

private static void generateBlocks() {
    System.out.format("%nGenerating %d input blocks...%n", CONCURRENT_THREADS_PER_TYPE);
    Random rand = new Random();
    MiningBlock parent, block, mainChain;
    mainChain = sourceChain.getGenesis();
    knownBlocks.add(mainChain);
    List<AionTransaction> txs;
    AionRepositoryImpl sourceRepo = sourceChain.getRepository();
    long time = System.currentTimeMillis();
    for (int i = 0; i < CONCURRENT_THREADS_PER_TYPE; i++) {
        // ensuring that we add to the main chain at least every MAIN_CHAIN_FREQUENCY block
        if (i % MAIN_CHAIN_FREQUENCY == 0) {
            // the parent will be the main chain
            parent = mainChain;
        } else {
            // the parent is a random already imported block
            parent = knownBlocks.get(rand.nextInt(knownBlocks.size()));
        }
        // generate transactions for correct root
        byte[] originalRoot = sourceRepo.getRoot();
        sourceRepo.syncToRoot(parent.getStateRoot());
        txs = generateTransactions(MAX_TX_PER_BLOCK, accounts, sourceRepo);
        sourceRepo.syncToRoot(originalRoot);
        block = sourceChain.createNewMiningBlockInternal(parent, txs, true, time / 10000L).block;
        MiningBlockHeader newBlockHeader = MiningBlockHeader.Builder.newInstance().withHeader(block.getHeader()).withExtraData(String.valueOf(i).getBytes()).build();
        block.updateHeader(newBlockHeader);
        ImportResult result = sourceChain.tryToConnect(block);
        knownBlocks.add(block);
        if (result == ImportResult.IMPORTED_BEST) {
            mainChain = block;
        }
        if (DISPLAY_MESSAGES) {
            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());
        }
    }
    // all blocks except the genesis will be imported by the other chain
    knownBlocks.remove(sourceChain.getGenesis());
}
Also used : MiningBlockHeader(org.aion.zero.impl.types.MiningBlockHeader) ImportResult(org.aion.zero.impl.core.ImportResult) Random(java.util.Random) AionTransaction(org.aion.base.AionTransaction) AionRepositoryImpl(org.aion.zero.impl.db.AionRepositoryImpl) MiningBlock(org.aion.zero.impl.types.MiningBlock)

Example 62 with MiningBlock

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

the class BlockchainConcurrentImportTest method addThread_tryToConnect.

/**
 * Adds a new thread for importing an already known block.
 *
 * @param _threads list of threads to be executed; the current thread will be added to this list
 * @param _chain the blockchain where the blocks will be imported
 * @param _block the block to import
 */
private void addThread_tryToConnect(List<Runnable> _threads, StandaloneBlockchain _chain, MiningBlock _block) {
    _threads.add(() -> {
        testChain.assertEqualTotalDifficulty();
        // importing the given block
        ImportResult result = _chain.tryToConnect(_block);
        testChain.assertEqualTotalDifficulty();
        if (DISPLAY_MESSAGES) {
            System.out.format("Import block with hash: %s, number: %6d, extra data: %6s, txs: %3d, status: %20s in thread: %20s %n", _block.getShortHash(), _block.getNumber(), new String(_block.getExtraData()), _block.getTransactionsList().size(), result.toString(), Thread.currentThread().getName());
        }
        // checking total difficulty
        if (result == ImportResult.IMPORTED_BEST || result == ImportResult.IMPORTED_NOT_BEST) {
            AionBlockStore store = _chain.getRepository().getBlockStore();
            BigInteger tdFromStore = _chain.getTotalDifficultyForHash(_block.getHash());
            BigInteger tdCalculated = _chain.getTotalDifficultyForHash(_block.getParentHash()).add(_block.getDifficultyBI());
            assertThat(tdFromStore).isEqualTo(tdCalculated);
            assertThat(tdCalculated).isEqualTo(_chain.getTotalDifficultyForHash(_block.getHash()));
            if (result == ImportResult.IMPORTED_BEST) {
                // can't check for equality since other blocks may have already been
                // imported
                Block bestBlock = store.getBestBlock();
                assertNotNull(bestBlock);
                assertThat(bestBlock.getTotalDifficulty()).isAtLeast(tdFromStore);
            }
        }
    });
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) BigInteger(java.math.BigInteger) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) AionBlockStore(org.aion.zero.impl.db.AionBlockStore)

Example 63 with MiningBlock

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

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

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

MiningBlock (org.aion.zero.impl.types.MiningBlock)185 Test (org.junit.Test)136 AionTransaction (org.aion.base.AionTransaction)128 ImportResult (org.aion.zero.impl.core.ImportResult)81 AionAddress (org.aion.types.AionAddress)79 BigInteger (java.math.BigInteger)64 Block (org.aion.zero.impl.types.Block)63 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)59 RepositoryCache (org.aion.base.db.RepositoryCache)41 AionTxReceipt (org.aion.base.AionTxReceipt)37 ArrayList (java.util.ArrayList)36 ECKey (org.aion.crypto.ECKey)27 AionRepositoryImpl (org.aion.zero.impl.db.AionRepositoryImpl)27 AionTxExecSummary (org.aion.base.AionTxExecSummary)25 AionRepositoryCache (org.aion.zero.impl.db.AionRepositoryCache)24 MiningBlockHeader (org.aion.zero.impl.types.MiningBlockHeader)22 BlockContext (org.aion.zero.impl.types.BlockContext)18 DataWord (org.aion.util.types.DataWord)13 MockDB (org.aion.db.impl.mockdb.MockDB)12 StakingBlock (org.aion.zero.impl.types.StakingBlock)11