use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class BlockchainForkingTest method testInvalidFirstBlockDifficulty.
/*-
* 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 testInvalidFirstBlockDifficulty() {
StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
StandaloneBlockchain.Bundle b = builder.withValidatorConfiguration("simple").build();
StandaloneBlockchain bc = b.bc;
Block bestBlock = bc.getBestBlock();
MiningBlock standardBlock = bc.createNewMiningBlock(bc.getBestBlock(), Collections.emptyList(), true);
ChainConfiguration cc = new ChainConfiguration();
MiningBlock higherDifficultyBlock = new MiningBlock(standardBlock);
MiningBlockHeader newBlockHeader = MiningBlockHeader.Builder.newInstance().withHeader(higherDifficultyBlock.getHeader()).withTimestamp(bestBlock.getTimestamp() + 1).build();
higherDifficultyBlock.updateHeader(newBlockHeader);
BigInteger difficulty = cc.getPreUnityDifficultyCalculator().calculateDifficulty(higherDifficultyBlock.getHeader(), bestBlock.getHeader());
assertThat(difficulty).isGreaterThan(standardBlock.getDifficultyBI());
newBlockHeader = MiningBlockHeader.Builder.newInstance().withHeader(higherDifficultyBlock.getHeader()).withDifficulty(difficulty.toByteArray()).build();
higherDifficultyBlock.updateHeader(newBlockHeader);
System.out.println("before any processing: " + Hex.toHexString(bc.getRepository().getRoot()));
System.out.println("trie: " + bc.getRepository().getWorldState().getTrieDump());
ImportResult result = bc.tryToConnect(standardBlock);
assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
// check that the correct caching context was used
Pair<Long, BlockCachingContext> cacheContext = bc.getAvmCachingContext();
assertThat(cacheContext.getLeft()).isEqualTo(standardBlock.getNumber() - 1);
assertThat(cacheContext.getRight()).isEqualTo(BlockCachingContext.MAINCHAIN);
// assert that the block we just inserted (best) is the instance that is returned
assertThat(bc.getBestBlock() == standardBlock).isTrue();
System.out.println(Hex.toHexString(bc.getRepository().getRoot()));
ImportResult higherDifficultyResult = bc.tryToConnect(higherDifficultyBlock);
/**
* With our updates to difficulty verification and calculation, this block is now invalid
*/
assertThat(higherDifficultyResult).isEqualTo(ImportResult.INVALID_BLOCK);
assertThat(bc.getBestBlockHash()).isEqualTo(standardBlock.getHash());
// since the block is second for that height, it is assumed as sidechain
cacheContext = bc.getAvmCachingContext();
assertThat(cacheContext.getLeft()).isEqualTo(standardBlock.getNumber() - 1);
assertThat(cacheContext.getRight()).isEqualTo(BlockCachingContext.SIDECHAIN);
// the object reference here is intentional
assertThat(bc.getBestBlock() == standardBlock).isTrue();
// check for correct state rollback
assertThat(bc.getRepository().getRoot()).isEqualTo(standardBlock.getStateRoot());
assertThat(bc.getTotalDifficulty()).isEqualTo(bc.getTotalDifficultyForHash(standardBlock.getHash()));
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionHubTest method MockHubInst_wStartAtBlock.
@Test
public void MockHubInst_wStartAtBlock() {
StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
StandaloneBlockchain chain = bundle.bc;
int expectedStartBlock = 6;
generateRandomChainWithoutTransactions(chain, expectedStartBlock, 1);
AionHub hub = AionHub.createForTesting(CfgAion.inst(), chain, new PendingTxCallback(new ArrayList<>()), new NetworkBestBlockCallback(AionImpl.inst()), new TransactionBroadcastCallback(AionImpl.inst()));
checkHubNullity(hub);
Block blk = hub.getStartingBlock();
assertThat(blk).isNotNull();
assertThat(blk.getNumber()).isEqualTo((long) expectedStartBlock);
hub.close();
assertThat(hub.isRunning()).isFalse();
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class AionHubTest method MockHubInst_wStartAtGenesis.
@Test
public void MockHubInst_wStartAtGenesis() {
StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
StandaloneBlockchain.Bundle bundle = builder.withValidatorConfiguration("simple").build();
StandaloneBlockchain chain = bundle.bc;
chain.setBestBlock(chain.getGenesis());
AionHub hub = AionHub.createForTesting(CfgAion.inst(), chain, new PendingTxCallback(new ArrayList<>()), new NetworkBestBlockCallback(AionImpl.inst()), new TransactionBroadcastCallback(AionImpl.inst()));
checkHubNullity(hub);
Block blk = hub.getStartingBlock();
assertThat(blk).isNotNull();
assertThat(blk.getNumber()).isEqualTo(0);
hub.close();
assertThat(hub.isRunning()).isFalse();
}
use of org.aion.zero.impl.types.Block 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);
}
}
});
}
use of org.aion.zero.impl.types.Block in project aion by aionnetwork.
the class BlockchainIndexIntegrityTest method testIndexIntegrityWithoutLevel.
/**
* Test the index integrity check and recovery when the index database is missing a level
* information.
*
* <p>Under these circumstances the recovery process will fail.
*/
@Test
public void testIndexIntegrityWithoutLevel() {
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;
ImportResult result;
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
Block next = chain.createNewMiningBlock(chain.getBestBlock(), Collections.emptyList(), true);
result = chain.tryToConnect(next);
assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
}
Block bestBlock = chain.getBestBlock();
assertThat(bestBlock.getNumber()).isEqualTo(NUMBER_OF_BLOCKS);
chain.getRepository().flush();
AionRepositoryImpl repo = chain.getRepository();
MockDB indexDatabase = (MockDB) repo.getIndexDatabase();
// deleting the level 2 index
indexDatabase.deleteAndCommit(ByteUtil.intToBytes(2));
AionBlockStore blockStore = repo.getBlockStore();
// check that the index recovery failed
assertThat(blockStore.indexIntegrityCheck()).isEqualTo(AionBlockStore.IntegrityCheckResult.MISSING_LEVEL);
}
Aggregations