use of org.aion.zero.impl.types.MiningBlock in project aion by aionnetwork.
the class BlockPropagationTest method testPropagateBlockToPeer.
// given two peers, and one sends you a new block, propagate to the other
@Test
public void testPropagateBlockToPeer() {
List<ECKey> accounts = generateDefaultAccounts();
StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).build();
MiningBlock block = bundle.bc.createNewMiningBlock(bundle.bc.getGenesis(), Collections.EMPTY_LIST, true);
assertThat(block.getNumber()).isEqualTo(1);
byte[] sender = HashUtil.h256("node1".getBytes());
byte[] receiver = HashUtil.h256("receiver".getBytes());
NodeMock senderMock = new NodeMock(sender, 1);
NodeMock receiverMock = new NodeMock(receiver, 0);
Map<Integer, INode> node = new HashMap<>();
node.put(1, senderMock);
node.put(2, receiverMock);
AtomicInteger times = new AtomicInteger();
P2pMock p2pMock = new P2pMock(node) {
@Override
public void send(int _nodeId, String s, Msg _msg) {
if (_nodeId != receiverMock.getIdHash()) {
throw new RuntimeException("should only send to receiver");
}
times.getAndIncrement();
}
};
StandaloneBlockchain.Bundle anotherBundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).withEventManger(this.loadEventMgr()).build();
assertThat(bundle.bc.genesis.getHash()).isEqualTo(anotherBundle.bc.genesis.getHash());
assertThat(block.getParentHash()).isEqualTo(bundle.bc.genesis.getHash());
assertThat(block.getParentHash()).isEqualTo(anotherBundle.bc.genesis.getHash());
Block bestBlock = bundle.bc.getBestBlock();
assertThat(bestBlock.getHash()).isEqualTo(anotherBundle.bc.genesis.getHash());
SyncStats syncStats = new SyncStats(bestBlock.getNumber(), true);
BlockPropagationHandler handler = new BlockPropagationHandler(1024, // NOTE: not the same blockchain that generated the block
anotherBundle.bc, syncStats, p2pMock, anotherBundle.bc.getBlockHeaderValidator(), false, (byte) 2, new AionPendingStateImpl(anotherBundle.bc, blockEnergyUpperBound, pendingTransactionTimeout, enablePoolBackup, enableSeedMode, enablePoolDump, new PendingTxCallback(new ArrayList<>()), new NetworkBestBlockCallback(AionImpl.inst()), new TransactionBroadcastCallback(AionImpl.inst()), true));
// block is processed
assertThat(handler.processIncomingBlock(senderMock.getIdHash(), "test", block)).isEqualTo(BlockPropagationHandler.PropStatus.PROP_CONNECTED);
assertThat(times.get()).isEqualTo(1);
}
use of org.aion.zero.impl.types.MiningBlock in project aion by aionnetwork.
the class BlockPropagationTest method testBlockPropagationReceiver.
/**
* Test that we don't propagate back to the sender
*/
@Test
public void testBlockPropagationReceiver() {
List<ECKey> accounts = generateDefaultAccounts();
StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).build();
MiningBlock block = bundle.bc.createNewMiningBlock(bundle.bc.getGenesis(), Collections.EMPTY_LIST, true);
assertThat(block.getNumber()).isEqualTo(1);
byte[] sender = HashUtil.h256("node1".getBytes());
NodeMock senderMock = new NodeMock(sender, 1);
Map<Integer, INode> node = new HashMap<>();
node.put(1, senderMock);
SyncStats syncStats = new SyncStats(block.getNumber(), true);
P2pMock p2pMock = new P2pMock(node) {
@Override
public void send(int _nodeId, String s, Msg _msg) {
throw new RuntimeException("should not have called send");
}
};
StandaloneBlockchain.Bundle anotherBundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).withEventManger(this.loadEventMgr()).build();
BlockPropagationHandler handler = new BlockPropagationHandler(1024, // NOTE: not the same blockchain that generated the block
anotherBundle.bc, syncStats, p2pMock, anotherBundle.bc.getBlockHeaderValidator(), false, (byte) 2, new AionPendingStateImpl(anotherBundle.bc, blockEnergyUpperBound, pendingTransactionTimeout, enablePoolBackup, enableSeedMode, enablePoolDump, new PendingTxCallback(new ArrayList<>()), new NetworkBestBlockCallback(AionImpl.inst()), new TransactionBroadcastCallback(AionImpl.inst()), true));
assertThat(handler.processIncomingBlock(senderMock.getIdHash(), "test", block)).isEqualTo(BlockPropagationHandler.PropStatus.CONNECTED);
}
use of org.aion.zero.impl.types.MiningBlock in project aion by aionnetwork.
the class BlockPropagationTest method testIgnoreSelfBlock.
// this test scenario: we propagate a block out, and someone propagates back
@Test
public void testIgnoreSelfBlock() {
List<ECKey> accounts = generateDefaultAccounts();
StandaloneBlockchain.Bundle bundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).build();
MiningBlock block = bundle.bc.createNewMiningBlock(bundle.bc.getGenesis(), Collections.EMPTY_LIST, true);
assertThat(block.getNumber()).isEqualTo(1);
byte[] sender = HashUtil.h256("node1".getBytes());
NodeMock senderMock = new NodeMock(sender, 1);
Map<Integer, INode> node = new HashMap<>();
node.put(1, senderMock);
AtomicInteger sendCount = new AtomicInteger();
P2pMock p2pMock = new P2pMock(node) {
@Override
public void send(int _nodeId, String s, Msg _msg) {
sendCount.getAndIncrement();
}
};
StandaloneBlockchain.Bundle anotherBundle = new StandaloneBlockchain.Builder().withValidatorConfiguration("simple").withDefaultAccounts(accounts).withEventManger(this.loadEventMgr()).build();
SyncStats syncStats = new SyncStats(bundle.bc.getBestBlock().getNumber(), true);
BlockPropagationHandler handler = new BlockPropagationHandler(1024, // NOTE: not the same blockchain that generated the block
anotherBundle.bc, syncStats, p2pMock, anotherBundle.bc.getBlockHeaderValidator(), false, (byte) 2, new AionPendingStateImpl(anotherBundle.bc, blockEnergyUpperBound, pendingTransactionTimeout, enablePoolBackup, enableSeedMode, enablePoolDump, new PendingTxCallback(new ArrayList<>()), new NetworkBestBlockCallback(AionImpl.inst()), new TransactionBroadcastCallback(AionImpl.inst()), true));
// pretend that we propagate the new block
// send counter incremented
handler.propagateNewBlock(block);
// recall that we're using another blockchain and faked the propagation
// so our blockchain should view this block as a new block
// therefore if the filter fails, this block will actually be CONNECTED
assertThat(handler.processIncomingBlock(senderMock.getIdHash(), "test", block)).isEqualTo(BlockPropagationHandler.PropStatus.DROPPED);
// we expect the counter to be incremented once (on propagation)
assertThat(sendCount.get()).isEqualTo(1);
}
use of org.aion.zero.impl.types.MiningBlock in project aion by aionnetwork.
the class PendingStateTest method replayTransactionThatThatInvalidatesMiddleTx.
@Test
public void replayTransactionThatThatInvalidatesMiddleTx() {
BigInteger balance = blockchain.getRepository().getBalance(new AionAddress(deployerKey.getAddress()));
BigInteger value = balance.subtract(BigInteger.valueOf(21000 * 7).multiply(BigInteger.valueOf(energyPrice)));
AionTransaction tx1 = AionTransaction.create(deployerKey, BigInteger.ZERO.toByteArray(), new AionAddress(new byte[32]), value.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
AionTransaction tx2 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
/* tx1 and tx3 should use the entire balance. If tx2 is removed properly, tx3 should be
* able to replace it in the pending state */
AionTransaction tx3 = AionTransaction.create(deployerKey, BigInteger.ONE.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice * 4, TransactionTypes.DEFAULT, null);
// This would execute fine on top of tx2, but should have insufficient balance on top of tx3
AionTransaction tx4 = AionTransaction.create(deployerKey, BigInteger.TWO.toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice * 4, TransactionTypes.DEFAULT, null);
AionTransaction tx5 = AionTransaction.create(deployerKey, BigInteger.valueOf(3).toByteArray(), new AionAddress(new byte[32]), BigInteger.ZERO.toByteArray(), new byte[0], 21000, energyPrice, TransactionTypes.DEFAULT, null);
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx1));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx2));
assertEquals(TxResponse.REPAID, pendingState.addTransactionFromApiServer(tx3));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx4));
assertEquals(TxResponse.SUCCESS, pendingState.addTransactionFromApiServer(tx5));
assertEquals(4, pendingState.getPendingTxSize());
MiningBlock block = blockchain.createNewMiningBlock(blockchain.getBestBlock(), Collections.emptyList(), false);
Pair<ImportResult, AionBlockSummary> connectResult = blockchain.tryToConnectAndFetchSummary(block);
assertEquals(connectResult.getLeft(), ImportResult.IMPORTED_BEST);
pendingState.applyBlockUpdate(block, connectResult.getRight().getReceipts());
// tx3 should replace tx2, and tx4 will now have insufficient funds so it will get dropped
assertEquals(2, pendingState.getPendingTxSize());
assertEquals(pendingState.getPendingTransactions().get(1), tx3);
}
use of org.aion.zero.impl.types.MiningBlock in project aion by aionnetwork.
the class BlockchainConcurrentImportTest method addThread_tryToConnect.
/**
* Adds a new thread for importing a block from the given queue.
*
* @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 _queue a queue containing new blocks
* @param _imported a list of blocks that have been imported; blocks successfully imported are
* added to this list
*/
private void addThread_tryToConnect(List<Runnable> _threads, StandaloneBlockchain _chain, ConcurrentLinkedQueue<MiningBlock> _queue, ConcurrentLinkedQueue<MiningBlock> _imported) {
_threads.add(() -> {
// get next block from queue
MiningBlock _block = _queue.poll();
if (_block != null) {
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 (from queue)%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
assertThat(store.getBestBlock().getTotalDifficulty()).isAtLeast(tdFromStore);
}
// save the block for later comparison
_imported.add(_block);
}
} else {
if (DISPLAY_MESSAGES) {
System.out.format("%62sNo block in queue. Skipping import in thread: %20s %n", " ", Thread.currentThread().getName());
}
}
});
}
Aggregations