Search in sources :

Example 6 with ImportResult

use of org.aion.mcf.core.ImportResult 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]
 *
 * Note: this test is resource consuming!
 *
 * 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;
    AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.EMPTY_LIST, true);
    ImportResult res = bc.tryToConnect(block);
    assertThat(res).isEqualTo(ImportResult.IMPORTED_BEST);
    Address coinbase = block.getCoinbase();
    BigInteger previousBalance = bc.getRepository().getBalance(coinbase);
    // first block already sealed
    for (int i = 2; i < 99999; i++) {
        AionBlock b = bc.createNewBlock(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.mcf.core.ImportResult) Address(org.aion.base.type.Address) BigInteger(java.math.BigInteger) AionBlock(org.aion.zero.impl.types.AionBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 7 with ImportResult

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

the class AionPoW method processSolution.

/**
 * Processes a received solution.
 *
 * @param solution
 *            The generated equihash solution
 */
protected synchronized void processSolution(Solution solution) {
    if (!shutDown.get()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Best block num [{}]", blockchain.getBestBlock().getNumber());
            LOG.debug("Best block nonce [{}]", Hex.toHexString(blockchain.getBestBlock().getNonce()));
            LOG.debug("Best block hash [{}]", Hex.toHexString(blockchain.getBestBlock().getHash()));
        }
        AionBlock block = (AionBlock) solution.getBlock();
        if (!Arrays.equals(block.getHeader().getNonce(), new byte[32])) {
            // block has been processed
            return;
        }
        // set the nonce and solution
        block.getHeader().setNonce(solution.getNonce());
        block.getHeader().setSolution(solution.getSolution());
        block.getHeader().setTimestamp(solution.getTimeStamp());
        // This can be improved
        ImportResult importResult = AionImpl.inst().addNewMinedBlock(block);
        // Check that the new block was successfully added
        if (importResult.isSuccessful()) {
            if (importResult == IMPORTED_BEST) {
                LOG.info("block sealed <num={}, hash={}, diff={}, tx={}>", block.getNumber(), block.getShortHash(), // LogUtil.toHexF8(newBlock.getHash()),
                block.getHeader().getDifficultyBI().toString(), block.getTransactionsList().size());
            } else {
                LOG.debug("block sealed <num={}, hash={}, diff={}, tx={}, result={}>", block.getNumber(), // LogUtil.toHexF8(newBlock.getHash()),
                block.getShortHash(), block.getHeader().getDifficultyBI().toString(), block.getTransactionsList().size(), importResult);
            }
        // TODO: fire block mined event
        } else {
            LOG.info("Unable to import a new mined block; restarting mining.\n" + "Mined block import result is " + importResult + " : " + block.getShortHash());
        }
    }
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) AionBlock(org.aion.zero.impl.types.AionBlock)

Example 8 with ImportResult

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

the class BlockPropagationHandler method processIncomingBlock.

public PropStatus processIncomingBlock(final int nodeId, final AionBlock block) {
    if (block == null)
        return PropStatus.DROPPED;
    ByteArrayWrapper hashWrapped = new ByteArrayWrapper(block.getHash());
    if (!this.blockHeaderValidator.validate(block.getHeader(), log))
        return PropStatus.DROPPED;
    // guarantees if multiple requests of same block appears, only one goes through
    synchronized (this.cacheMap) {
        if (this.cacheMap.containsKey(hashWrapped))
            return PropStatus.DROPPED;
        // regardless if block processing is successful, place into cache
        this.cacheMap.put(hashWrapped, true);
    }
    AionBlock bestBlock = this.blockchain.getBestBlock();
    // assumption is that we are on the correct chain
    if (bestBlock.getNumber() > block.getNumber())
        return PropStatus.DROPPED;
    // this implies we only propagate blocks from our own chain
    if (!bestBlock.isParentOf(block))
        return PropStatus.DROPPED;
    // send
    boolean sent = send(block, nodeId);
    // process
    ImportResult result = this.blockchain.tryToConnect(block);
    // process resulting state
    if (sent && result.isSuccessful())
        return PropStatus.PROP_CONNECTED;
    if (result.isSuccessful())
        return PropStatus.CONNECTED;
    if (sent)
        return PropStatus.PROPAGATED;
    // should never reach here, but just in case
    return PropStatus.DROPPED;
}
Also used : ImportResult(org.aion.mcf.core.ImportResult) ByteArrayWrapper(org.aion.base.util.ByteArrayWrapper) AionBlock(org.aion.zero.impl.types.AionBlock)

Example 9 with ImportResult

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

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithPartialWorldState.

/**
 * Test the recovery of the world state in the case where it is missing from the database.
 */
@Test
public void testRecoverWorldStateWithPartialWorldState() {
    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;
    // first half of blocks will be correct
    ImportResult result;
    for (int i = 0; i < NUMBER_OF_BLOCKS / 2; i++) {
        result = chain.tryToConnect(chain.createNewBlock(chain.getBestBlock(), Collections.emptyList(), true));
        assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    }
    // second half of blocks will miss the state root
    List<byte[]> statesToDelete = new ArrayList<>();
    for (int i = 0; i < NUMBER_OF_BLOCKS / 2; 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();
    // 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();
    }
    // 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 10 with ImportResult

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

the class BlockchainDataRecoveryTest method testRecoverWorldStateWithoutGenesis.

/**
 * Test the recovery of the world state in the case where it is missing from the database.
 */
@Test
public void testRecoverWorldStateWithoutGenesis() {
    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;
    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);
    }
    AionBlock bestBlock = chain.getBestBlock();
    assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
    chain.getRepository().flush();
    // delete some world state root entries from the database
    TrieImpl trie = (TrieImpl) ((AionRepositoryImpl) chain.getRepository()).getWorldState();
    IByteArrayKeyValueDatabase database = (IByteArrayKeyValueDatabase) trie.getCache().getDb();
    List<byte[]> statesToDelete = new ArrayList<>();
    statesToDelete.addAll(database.keys());
    for (byte[] key : statesToDelete) {
        database.delete(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(chain.getRepository(), bestBlock.getNumber());
    // ensure that the blockchain is ok
    assertThat(chain.getBestBlockHash()).isEqualTo(bestBlock.getHash());
    // ensure that the world state was not recovered
    assertThat(worked).isFalse();
    assertThat(trie.isValidRoot(chain.getBestBlock().getStateRoot())).isFalse();
}
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)

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