Search in sources :

Example 71 with MiningBlock

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

the class BlockchainRewardTest method testBlockchainRewardMonotonicallyIncreasing.

/**
 * Test that blocks between the lower and upper bounds follow a certain function [0, 259200]
 *
 * <p>Note: this test is resource consuming!
 *
 * <p>Check {@link org.aion.zero.impl.core.RewardsCalculator} for algorithm related to the
 * ramp-up block time
 */
@Ignore
@Test
public void testBlockchainRewardMonotonicallyIncreasing() {
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withDefaultAccounts().withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = bundle.bc;
    MiningBlock block = bc.createNewMiningBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    ImportResult res = bc.tryToConnect(block);
    assertThat(res).isEqualTo(ImportResult.IMPORTED_BEST);
    AionAddress coinbase = block.getCoinbase();
    BigInteger previousBalance = bc.getRepository().getBalance(coinbase);
    // first block already sealed
    for (int i = 2; i < 99999; i++) {
        MiningBlock b = bc.createNewMiningBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
        ImportResult r = bc.tryToConnect(b);
        assertThat(r).isEqualTo(ImportResult.IMPORTED_BEST);
        // note the assumption here that blocks are mined by one coinbase
        BigInteger balance = bc.getRepository().getBalance(coinbase);
        assertThat(balance).isGreaterThan(previousBalance);
        previousBalance = balance;
        if (b.getNumber() % 1000 == 0)
            System.out.println("added block #: " + i);
    }
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) AionAddress(org.aion.types.AionAddress) BigInteger(java.math.BigInteger) MiningBlock(org.aion.zero.impl.types.MiningBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 72 with MiningBlock

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

the class BlockchainAccountStateBenchmark method testExpandOneAccountStorage.

@Ignore
@Test
public void testExpandOneAccountStorage() throws InterruptedException {
    try {
        StandaloneBlockchain.Bundle bundle = this.bundle;
        StandaloneBlockchain bc = bundle.bc;
        ECKey senderKey = bundle.privateKeys.get(0);
        // deploy contract
        Pair<MiningBlock, byte[]> res = createContract(bc, senderKey, bc.getGenesis());
        bc.tryToConnect(res.getLeft());
        AionTxInfo info = bc.getTransactionInfo(res.getRight());
        assertThat(info.getReceipt().isValid()).isTrue();
        AionTransaction tx = info.getReceipt().getTransaction();
        AionAddress contractAddress = TxUtil.calculateContractAddress(tx);
        byte[] contractCode = bc.getRepository().getCode(contractAddress);
        System.out.println("deployed contract code: " + ByteUtil.toHexString(contractCode));
        System.out.println("deployed at: " + contractAddress);
        for (int i = 0; i < 100; i++) createContractBundle(bc, senderKey, bc.getBestBlock(), contractAddress);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        bundle.bc.getRepository().close();
        Thread.sleep(1000L);
    }
}
Also used : AionAddress(org.aion.types.AionAddress) AionTxInfo(org.aion.zero.impl.types.AionTxInfo) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 73 with MiningBlock

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

the class BlockchainConcurrencyTest method testPublishBestBlockSafely.

@Test
public void testPublishBestBlockSafely() {
    ExecutorService blockCreationService = Executors.newSingleThreadExecutor();
    ExecutorService getBlockService = Executors.newSingleThreadExecutor();
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withDefaultAccounts().withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = bundle.bc;
    final int MAX_COUNT = 100000;
    final CountDownLatch endLatch = new CountDownLatch(2);
    // this will not definitively prove
    try {
        blockCreationService.submit(() -> {
            int count = 0;
            List<AionTransaction> txList = Collections.emptyList();
            MiningBlock block = null;
            try {
                block = bc.createNewMiningBlock(bc.genesis, Collections.emptyList(), false);
            } catch (Exception e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted() && count < MAX_COUNT) {
                try {
                    block = bc.createNewMiningBlock(block, txList, false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                count++;
            }
            System.out.println("completed block creation");
            endLatch.countDown();
        });
        getBlockService.submit(() -> {
            int count = 0;
            long prevNumber = bc.getBestBlock().getNumber();
            while (!Thread.currentThread().isInterrupted() && count < MAX_COUNT) {
                // all three of these methods use {@link
                // AionBlockchainImpl#pubBestBlock}
                assertThat(bc.getBestBlockHash()).isNotNull();
                bc.getSize();
                Block block = bc.getBestBlock();
                assertThat(block).isNotNull();
                assertThat(block.getNumber()).isAtLeast(prevNumber);
                prevNumber = block.getNumber();
                count++;
            }
            endLatch.countDown();
        });
    } finally {
        blockCreationService.shutdown();
        getBlockService.shutdown();
    }
}
Also used : ExecutorService(java.util.concurrent.ExecutorService) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) AionTransaction(org.aion.base.AionTransaction) CountDownLatch(java.util.concurrent.CountDownLatch) MiningBlock(org.aion.zero.impl.types.MiningBlock) Test(org.junit.Test)

Example 74 with MiningBlock

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

the class BlockchainDataRecoveryTest method testRecoverIndex_wDeletedBlock.

@Test
public void testRecoverIndex_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();
    Map<Long, byte[]> blocksToDelete = new HashMap<>();
    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);
        blocksToDelete.put(context.block.getNumber(), context.block.getHash());
        // 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 index entries from the database
    MockDB indexDatabase = (MockDB) repo.getIndexDatabase();
    // 1: direct recovery call
    repo.flush();
    Map<Long, byte[]> deletedInfo = new HashMap<>();
    for (Map.Entry<Long, byte[]> entry : blocksToDelete.entrySet()) {
        byte[] indexKey = ByteUtil.intToBytes(entry.getKey().intValue());
        // saving the data for checking recovery
        deletedInfo.put(entry.getKey(), indexDatabase.get(indexKey).get());
        // deleting the block info
        indexDatabase.deleteAndCommit(indexKey);
        // ensure that the index was corrupted
        assertThat(repo.isIndexed(entry.getValue(), entry.getKey())).isFalse();
    }
    // ensure that the index was corrupted
    assertThat(repo.isIndexed(bestBlock.getHash(), bestBlock.getNumber())).isFalse();
    // call the recovery functionality
    assertThat(chain.recoverIndexEntry(repo, bestBlock)).isFalse();
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the index was recovered
    assertThat(repo.isIndexed(bestBlock.getHash(), bestBlock.getNumber())).isFalse();
    // 2: recovery at import
    repo.flush();
    for (Map.Entry<Long, byte[]> entry : blocksToDelete.entrySet()) {
        byte[] indexKey = ByteUtil.intToBytes(entry.getKey().intValue());
        // deleting the block info
        indexDatabase.deleteAndCommit(indexKey);
        // ensure that the index was corrupted
        assertThat(repo.isIndexed(entry.getValue(), entry.getKey())).isFalse();
    }
    // ensure that the index was corrupted
    assertThat(repo.isIndexed(bestBlock.getHash(), bestBlock.getNumber())).isFalse();
    // call the recovery functionality indirectly
    for (MiningBlock block : blocksToImport) {
        // index missing before import
        assertThat(repo.isIndexed(block.getHash(), block.getNumber())).isFalse();
        assertThat(chain.tryToConnect(block)).isEqualTo(ImportResult.EXIST);
        if (block.getNumber() < middle.getNumber()) {
            // index present after import
            assertThat(repo.isIndexed(block.getHash(), block.getNumber())).isTrue();
        } else {
            // blocks after missing one cannot be recovered
            assertThat(repo.isIndexed(block.getHash(), block.getNumber())).isFalse();
        }
    }
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the index was recovered
    assertThat(repo.isIndexed(bestBlock.getHash(), bestBlock.getNumber())).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()) {
            // index missing before import
            assertThat(repo.isIndexed(block.getHash(), block.getNumber())).isFalse();
            assertThat(chain.tryToConnect(block)).isEqualTo(ImportResult.EXIST);
            // index present after import
            assertThat(repo.isIndexed(block.getHash(), block.getNumber())).isTrue();
        }
    }
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the index was recovered
    assertThat(repo.isIndexed(bestBlock.getHash(), bestBlock.getNumber())).isTrue();
    // check that the index information is correct at database level
    for (Long key : blocksToDelete.keySet()) {
        // checking at database level
        byte[] indexKey = ByteUtil.intToBytes(key.intValue());
        assertThat(deletedInfo.get(key)).isEqualTo(indexDatabase.get(indexKey).get());
    }
}
Also used : HashMap(java.util.HashMap) 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) MiningBlock(org.aion.zero.impl.types.MiningBlock) Block(org.aion.zero.impl.types.Block) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Example 75 with MiningBlock

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

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithStartFromGenesis.

/**
 * Test the recovery of the world state with start from the state of the genesis block.
 */
@Test
public void testRecoverWorldStateWithStartFromGenesis() {
    // 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());
        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();
    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 is ok
    assertThat(worked).isTrue();
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isTrue();
    // 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 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)

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