Search in sources :

Example 1 with AionBlock

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

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithStartFromGenesis.

/**
 * Test the recovery of the world state in the case where it is missing from the database.
 */
@Test
public void testRecoverWorldStateWithStartFromGenesis() {
    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;
    List<byte[]> statesToDelete = new ArrayList<>();
    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);
        statesToDelete.add(next.getStateRoot());
    }
    AionBlock bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    // System.out.println(Hex.toHexString(chain.getRepository().getRoot()));
    // 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();
    }
    // System.out.println(Hex.toHexString(chain.getRepository().getRoot()));
    // 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 2 with AionBlock

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

the class BlockchainDifficultyTest method difficultySetTest.

@Test
public void difficultySetTest() {
    final long TIME_DIFFERENCE = 10l;
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withDefaultAccounts().withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = bundle.bc;
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    assertThat(block.getDifficultyBI()).isLessThan(bc.getGenesis().getDifficultyBI());
}
Also used : AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 3 with AionBlock

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

the class BlockchainEnergyTest method testConsistentEnergyUsage.

@Test
public void testConsistentEnergyUsage() {
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    // in cases where no transactions are included (no energy usage)
    // the default energy limit should persist (it should not degrade)
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    assertThat(block.getNrgLimit()).isEqualTo(bc.getGenesis().getNrgLimit());
}
Also used : AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 4 with AionBlock

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

the class BlockchainEnergyTest method testEnergyUsageRecorded.

@Test
public void testEnergyUsageRecorded() {
    final int DEFAULT_TX_AMOUNT = 21000;
    final Address RECEIPT_ADDR = Address.wrap("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE");
    StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withDefaultAccounts().withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = bundle.bc;
    // TODO: where is the 21000 defined? bad to define magic variables
    int amount = (int) (bc.getGenesis().getNrgLimit() / DEFAULT_TX_AMOUNT);
    // (byte[] nonce, byte[] from, byte[] to, byte[] value, byte[] data, byte[] nrg, byte[] nrgPrice)
    List<AionTransaction> txs = new ArrayList<>();
    for (int i = 0; i < amount; i++) {
        // this transaction should send one (1) AION coin from acc[0] to RECEIPT_ADDR
        AionTransaction atx = new AionTransaction(ByteUtil.intToBytes(i), RECEIPT_ADDR, BigInteger.ONE.toByteArray(), ByteUtil.EMPTY_BYTE_ARRAY, 21000L, BigInteger.valueOf(5).multiply(BigInteger.TEN.pow(9)).longValue());
        atx.sign(bundle.privateKeys.get(0));
        txs.add(atx);
    }
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), txs, true);
    ImportResult result = bc.tryToConnect(block);
    assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    // proceed with connecting the next block, should observe an increase in energyLimit
    AionBlock secondBlock = bc.createNewBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    assertThat(secondBlock.getNrgLimit()).isEqualTo(block.getNrgLimit());
    System.out.println(String.format("%d > %d", secondBlock.getNrgLimit(), block.getNrgLimit()));
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) Address(org.aion.base.type.Address) ArrayList(java.util.ArrayList) AionTransaction(org.aion.zero.types.AionTransaction) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 5 with AionBlock

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

the class BlockchainForkingTest method testHigherDifficultyBlockFork.

/*-
     * Test the general forking case, where an incoming block (b) has a greater total
     * difficulty than our current block. In this scenario, we should switch to
     * the branch (sub-tree) that has (b) at its tip.
     *
     * This is the simplest case, where the distance between (a) (our current head) and
     * (b) is 2. This implies that the common ancestor is directly adjacent to both blocks.
     *
     *          (common ancestor)
     *          /               \
     *         /                 \
     *        /                   \
     *       (a)x(low td)           (b)o(higher td)
     *
     * In this simple case:
     * b.td > a.td
     * a_worldState === b_worldState
     *
     */
@Test
public void testHigherDifficultyBlockFork() {
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain.Bundle b = builder.withValidatorConfiguration("simple").build();
    StandaloneBlockchain bc = b.bc;
    AionBlock bestBlock = bc.getBestBlock();
    AionBlock standardBlock = bc.createNewBlock(bc.getBestBlock(), Collections.emptyList(), true);
    ChainConfiguration cc = new ChainConfiguration();
    AionBlock higherDifficultyBlock = new AionBlock(standardBlock);
    higherDifficultyBlock.getHeader().setTimestamp(bestBlock.getTimestamp() + 1);
    BigInteger difficulty = cc.getDifficultyCalculator().calculateDifficulty(higherDifficultyBlock.getHeader(), bestBlock.getHeader());
    assertThat(difficulty).isGreaterThan(standardBlock.getDifficultyBI());
    higherDifficultyBlock.getHeader().setDifficulty(difficulty.toByteArray());
    System.out.println("before any processing: " + new ByteArrayWrapper(bc.getRepository().getRoot()));
    System.out.println("trie: " + ((AionRepositoryImpl) bc.getRepository()).getWorldState().getTrieDump());
    ImportResult result = bc.tryToConnect(standardBlock);
    assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    // assert that the block we just inserted (best) is the instance that is returned
    assertThat(bc.getBestBlock() == standardBlock).isTrue();
    System.out.println(new ByteArrayWrapper(bc.getRepository().getRoot()));
    ImportResult higherDifficultyResult = bc.tryToConnect(higherDifficultyBlock);
    assertThat(higherDifficultyResult).isEqualTo(ImportResult.IMPORTED_BEST);
    assertThat(bc.getBestBlockHash()).isEqualTo(higherDifficultyBlock.getHash());
    // the object reference here is intentional
    assertThat(bc.getBestBlock() == higherDifficultyBlock).isTrue();
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) ByteArrayWrapper(org.aion.base.util.ByteArrayWrapper) ChainConfiguration(org.aion.zero.impl.blockchain.ChainConfiguration) BigInteger(java.math.BigInteger) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Aggregations

AionBlock (org.aion.zero.impl.types.AionBlock)49 Test (org.junit.Test)16 ImportResult (org.aion.mcf.core.ImportResult)15 AionTransaction (org.aion.zero.types.AionTransaction)11 BigInteger (java.math.BigInteger)9 Address (org.aion.base.type.Address)6 ArrayList (java.util.ArrayList)5 JSONObject (org.json.JSONObject)5 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 ByteArrayWrapper (org.aion.base.util.ByteArrayWrapper)3 TrieImpl (org.aion.mcf.trie.TrieImpl)3 AionTxInfo (org.aion.zero.impl.types.AionTxInfo)3 A0BlockHeader (org.aion.zero.types.A0BlockHeader)3 Map (java.util.Map)2 ByteUtil.toHexString (org.aion.base.util.ByteUtil.toHexString)2 ECKey (org.aion.crypto.ECKey)2 IEvent (org.aion.evtmgr.IEvent)2 LRUMap (org.apache.commons.collections4.map.LRUMap)2 JSONArray (org.json.JSONArray)2 Ignore (org.junit.Ignore)2