@Test public void initializeNew() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); assertBlockDataIsStored(blockchain, genesisBlock, Collections.emptyList()); assertBlockIsHead(blockchain, genesisBlock); assertTotalDifficultiesAreConsistent(blockchain, genesisBlock); assertThat(blockchain.getForks()).isEmpty(); }
@Test public void appendBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); blockchain.appendBlock(newBlock, receipts); assertBlockIsHead(blockchain, newBlock); assertTotalDifficultiesAreConsistent(blockchain, newBlock); assertThat(blockchain.getForks()).isEmpty(); }
@Test(expected = IllegalArgumentException.class) public void initializeExistingWithWrongGenesisBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); // Write to kv store final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); createBlockchain(kvStore, genesisBlock); // Initialize a new blockchain store with same kvStore, but different genesis block createBlockchain(kvStore, gen.genesisBlock()); }
chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); assertBlockDataIsStored(blockchain, reorgedChain.get(i), reorgedReceipts.get(i));
@Test public void blockAddedObserver_addRemoveSingle() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final long observerId = blockchain.observeBlockAdded((block, chain) -> {}); assertThat(blockchain.observerCount()).isEqualTo(1); assertThat(blockchain.removeObserver(observerId)).isTrue(); assertThat(blockchain.observerCount()).isEqualTo(0); }
@Test public void initializeExisting() { final BlockDataGenerator gen = new BlockDataGenerator(); // Write to kv store final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); createBlockchain(kvStore, genesisBlock); // Initialize a new blockchain store with kvStore that already contains data final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); assertBlockDataIsStored(blockchain, genesisBlock, Collections.emptyList()); assertBlockIsHead(blockchain, genesisBlock); assertTotalDifficultiesAreConsistent(blockchain, genesisBlock); assertThat(blockchain.getForks()).isEmpty(); }
@Test public void blockAddedObserver_removeNonexistentObserver() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); assertThat(blockchain.removeObserver(7)).isFalse(); }
@Test public void createSmallChain() { final BlockDataGenerator gen = new BlockDataGenerator(); final List<Block> chain = gen.blockSequence(3); final List<List<TransactionReceipt>> blockReceipts = chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); } for (int i = 1; i < chain.size(); i++) { assertBlockDataIsStored(blockchain, chain.get(i), blockReceipts.get(i)); } final Block head = chain.get(chain.size() - 1); assertBlockIsHead(blockchain, head); assertTotalDifficultiesAreConsistent(blockchain, head); assertThat(blockchain.getForks()).isEmpty(); }
@Test public void blockAddedObserver_addRemoveMultiple() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final long observerId1 = blockchain.observeBlockAdded((block, chain) -> {}); assertThat(blockchain.observerCount()).isEqualTo(1); final long observerId2 = blockchain.observeBlockAdded((block, chain) -> {}); assertThat(blockchain.observerCount()).isEqualTo(2); final long observerId3 = blockchain.observeBlockAdded((block, chain) -> {}); assertThat(blockchain.observerCount()).isEqualTo(3); assertThat(blockchain.removeObserver(observerId1)).isTrue(); assertThat(blockchain.observerCount()).isEqualTo(2); assertThat(blockchain.removeObserver(observerId2)).isTrue(); assertThat(blockchain.observerCount()).isEqualTo(1); assertThat(blockchain.removeObserver(observerId3)).isTrue(); assertThat(blockchain.observerCount()).isEqualTo(0); }
chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); assertBlockDataIsStored(blockchain, reorgedChain.get(i), reorgedReceipts.get(i)); assertBlockIsHead(blockchain, fork); assertTotalDifficultiesAreConsistent(blockchain, fork);
@Test public void blockAddedObserver_invokedMultiple() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); final AtomicBoolean observer1Invoked = new AtomicBoolean(false); blockchain.observeBlockAdded( (block, chain) -> { observer1Invoked.set(true); }); final AtomicBoolean observer2Invoked = new AtomicBoolean(false); blockchain.observeBlockAdded( (block, chain) -> { observer2Invoked.set(true); }); final AtomicBoolean observer3Invoked = new AtomicBoolean(false); blockchain.observeBlockAdded( (block, chain) -> { observer3Invoked.set(true); }); blockchain.appendBlock(newBlock, receipts); assertThat(observer1Invoked.get()).isTrue(); assertThat(observer2Invoked.get()).isTrue(); assertThat(observer3Invoked.get()).isTrue(); }
chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); assertBlockDataIsStored(blockchain, chain.get(i), blockReceipts.get(i)); assertBlockIsHead(blockchain, originalHead); assertTotalDifficultiesAreConsistent(blockchain, originalHead); assertBlockDataIsStored(blockchain, reorgedChain.get(i), reorgedReceipts.get(i)); assertBlockIsHead(blockchain, forkBlocks.get(1)); assertTotalDifficultiesAreConsistent(blockchain, forkBlocks.get(1));
@Test(expected = NullPointerException.class) public void blockAddedObserver_nullObserver() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); blockchain.observeBlockAdded(null); }
chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); assertBlockDataIsStored(blockchain, chain.get(i), blockReceipts.get(i)); assertBlockIsHead(blockchain, originalHead); assertTotalDifficultiesAreConsistent(blockchain, originalHead); assertBlockDataIsStored(blockchain, reorgedChain.get(i), reorgedReceipts.get(i)); assertBlockIsHead(blockchain, forkBlocks.get(1)); assertTotalDifficultiesAreConsistent(blockchain, forkBlocks.get(1));
@Test public void blockAddedObserver_invokedSingle() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); final AtomicBoolean observerInvoked = new AtomicBoolean(false); blockchain.observeBlockAdded( (block, chain) -> { observerInvoked.set(true); }); blockchain.appendBlock(newBlock, receipts); assertThat(observerInvoked.get()).isTrue(); }
chain.stream().map(gen::receipts).collect(Collectors.toList()); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, chain.get(0)); for (int i = 1; i < chain.size(); i++) { blockchain.appendBlock(chain.get(i), blockReceipts.get(i)); assertBlockDataIsStored(blockchain, chain.get(j), blockReceipts.get(j)); assertBlockIsHead(blockchain, originalHead); assertTotalDifficultiesAreConsistent(blockchain, originalHead); assertBlockIsHead(blockchain, originalHead);
@Test(expected = IllegalArgumentException.class) public void appendBlockWithMismatchedReceipts() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(genesisBlock.getHash()); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); receipts.add(gen.receipt()); blockchain.appendBlock(newBlock, receipts); }
@Test(expected = IllegalArgumentException.class) public void appendUnconnectedBlock() { final BlockDataGenerator gen = new BlockDataGenerator(); final KeyValueStorage kvStore = new InMemoryKeyValueStorage(); final Block genesisBlock = gen.genesisBlock(); final DefaultMutableBlockchain blockchain = createBlockchain(kvStore, genesisBlock); final BlockOptions options = new BlockOptions().setBlockNumber(1L).setParentHash(Hash.ZERO); final Block newBlock = gen.block(options); final List<TransactionReceipt> receipts = gen.receipts(newBlock); blockchain.appendBlock(newBlock, receipts); }