Search in sources :

Example 1 with ImportResult

use of org.aion.mcf.core.ImportResult 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 ImportResult

use of org.aion.mcf.core.ImportResult 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 3 with ImportResult

use of org.aion.mcf.core.ImportResult 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)

Example 4 with ImportResult

use of org.aion.mcf.core.ImportResult in project aion by aionnetwork.

the class BlockchainIntegrationTest method testSimpleOneTokenBalanceTransfer.

@Test
public void testSimpleOneTokenBalanceTransfer() {
    // generate a recipient
    final Address receiverAddress = Address.wrap(ByteUtil.hexStringToBytes("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"));
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    final ECKey sender = bundle.privateKeys.get(0);
    final BigInteger senderInitialBalance = bc.getRepository().getBalance(Address.wrap(sender.getAddress()));
    AionTransaction tx = new AionTransaction(BigInteger.valueOf(0).toByteArray(), receiverAddress, BigInteger.valueOf(100).toByteArray(), ByteUtil.EMPTY_BYTE_ARRAY, 21000L, 1L);
    tx.sign(sender);
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.singletonList(tx), true);
    assertThat(block.getTransactionsList().size()).isEqualTo(1);
    assertThat(block.getTransactionsList().get(0)).isEqualTo(tx);
    ImportResult connection = bc.tryToConnect(block);
    assertThat(connection).isEqualTo(ImportResult.IMPORTED_BEST);
    // to be sure, perform some DB tests
    IRepository repo = bc.getRepository();
    assertThat(repo.getBalance(receiverAddress)).isEqualTo(BigInteger.valueOf(100));
    assertThat(repo.getBalance(Address.wrap(sender.getAddress()))).isEqualTo(senderInitialBalance.subtract(BigInteger.valueOf(21000)).subtract(BigInteger.valueOf(100)));
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) Address(org.aion.base.type.Address) BigInteger(java.math.BigInteger) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.zero.types.AionTransaction) IRepository(org.aion.base.db.IRepository) AionBlock(org.aion.zero.impl.types.AionBlock) Test(org.junit.Test)

Example 5 with ImportResult

use of org.aion.mcf.core.ImportResult in project aion by aionnetwork.

the class BlockchainIntegrationTest method testPruningEnabledBalanceTransfer.

@Ignore
@Test
public void testPruningEnabledBalanceTransfer() {
    // generate a recipient
    final Address receiverAddress = Address.wrap(ByteUtil.hexStringToBytes("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"));
    // generate bc bundle with pruning enabled
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withBlockPruningEnabled().withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    // desginate the first account in our list of private keys as the sender
    // (each key in the bundle is preloaded with balance)
    final ECKey sender = bundle.privateKeys.get(0);
    // generate transaction that transfers 100 tokens from sender to receiver
    // pk[0] -> receiverAddress
    AionTransaction tx = new AionTransaction(BigInteger.valueOf(0).toByteArray(), receiverAddress, BigInteger.valueOf(100).toByteArray(), ByteUtil.EMPTY_BYTE_ARRAY, 21000L, 1L);
    tx.sign(sender);
    // create a new block containing a single transaction (tx)
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.singletonList(tx), true);
    // import the block to our blockchain
    ImportResult connection = bc.tryToConnect(block);
    assertThat(connection).isEqualTo(ImportResult.IMPORTED_BEST);
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) Address(org.aion.base.type.Address) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.zero.types.AionTransaction) AionBlock(org.aion.zero.impl.types.AionBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Aggregations

ImportResult (org.aion.mcf.core.ImportResult)16 AionBlock (org.aion.zero.impl.types.AionBlock)14 Test (org.junit.Test)11 Address (org.aion.base.type.Address)5 BigInteger (java.math.BigInteger)4 ArrayList (java.util.ArrayList)4 AionTransaction (org.aion.zero.types.AionTransaction)4 IByteArrayKeyValueDatabase (org.aion.base.db.IByteArrayKeyValueDatabase)3 TrieImpl (org.aion.mcf.trie.TrieImpl)3 ByteArrayWrapper (org.aion.base.util.ByteArrayWrapper)2 ECKey (org.aion.crypto.ECKey)2 Ignore (org.junit.Ignore)2 Date (java.util.Date)1 IRepository (org.aion.base.db.IRepository)1 IEvent (org.aion.evtmgr.IEvent)1 EventBlock (org.aion.evtmgr.impl.evt.EventBlock)1 ChainConfiguration (org.aion.zero.impl.blockchain.ChainConfiguration)1 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)1