Skip to content

Commit

Permalink
Add tests for getThreeGenerationBlocksByHashWithInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandraRoatis committed Mar 12, 2020
1 parent be87c4a commit 3cdd7e3
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1666,12 +1666,10 @@ public boolean isValid(BlockHeader header) {
}

Block[] threeGenParents = repository.getBlockStore().getThreeGenerationBlocksByHashWithInfo(header.getParentHash());

if (threeGenParents == null) {
Block parentBlock = threeGenParents[0];
if (parentBlock == null) {
return false;
}

Block parentBlock = threeGenParents[0];
Block grandparentBlock = threeGenParents[1];
Block greatGrandparentBlock = threeGenParents[2];

Expand Down
17 changes: 10 additions & 7 deletions modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -1392,18 +1392,21 @@ void redoIndexWithoutSideChains(Block block) {
}

/**
* Retrieve three generation blocks with unity protocol info with one lock.
* @param hash given hash of the block
* @return the 3 generation block data have matched hash with unity protocol info. Block[0] is the parent block,
* Block[1] is the grandParent block, and Block[2] is the greatParentBlock. The return might only contain the parent
* block and still return the 3-elements array.
* Retrieves three generation blocks with unity protocol info.
* <p>
* Always returns a 3-element array. If the blocks cannot be retrieved the array will contain null values.
* Block[0] is the parent block and has the given hash. Block[1] is the grandparent block.
* Block[2] is the great grandparent block.
*
* @param hash the hash of the parent block
* @return the retrieved three generation blocks with unity protocol info
*/
public final Block[] getThreeGenerationBlocksByHashWithInfo(byte[] hash) {
Block[] blockFamily = new Block[] { null, null, null};
if (hash == null) {
return null;
return blockFamily;
}

Block[] blockFamily = new Block[] { null, null, null};
lock.lock();

try {
Expand Down
137 changes: 137 additions & 0 deletions modAionImpl/test/org/aion/zero/impl/db/AionBlockStoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -562,4 +562,141 @@ public void testGetTwoGenerationBlocksByHashWithInfo_withSidechainGrandparent()
assertThat(blocks[1].getTotalDifficulty()).isEqualTo(BigInteger.TWO);
assertThat(blocks[1].isMainChain()).isFalse();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo_withNullInput() {
AionBlockStore store = new AionBlockStore(index, blocks, false);
Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(null);
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isNull();
assertThat(blocks[1]).isNull();
assertThat(blocks[2]).isNull();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo_withMissingParent() {
byte[] parentHash = RandomUtils.nextBytes(32);

AionBlockStore store = new AionBlockStore(index, blocks, false);
assertThat(index.isEmpty()).isTrue();
assertThat(blocks.isEmpty()).isTrue();

Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(parentHash);
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isNull();
assertThat(blocks[1]).isNull();
assertThat(blocks[2]).isNull();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo_withMissingGrandparent() {
Block parent = consecutiveBlocks.get(0);

AionBlockStore store = new AionBlockStore(index, blocks, false);
// does not require accurate total difficulty
store.saveBlock(parent, BigInteger.TEN, true);

Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(parent.getHash());
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isEqualTo(parent);
assertThat(blocks[0].getTotalDifficulty()).isEqualTo(BigInteger.TEN);
assertThat(blocks[0].isMainChain()).isTrue();
assertThat(blocks[1]).isNull();
assertThat(blocks[2]).isNull();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo_withMissingGreatGrandparent() {
Block grandparent = consecutiveBlocks.get(0);
Block parent = consecutiveBlocks.get(1);

AionBlockStore store = new AionBlockStore(index, blocks, false);
// does not require accurate total difficulty
store.saveBlock(grandparent, BigInteger.TWO, true);
store.saveBlock(parent, BigInteger.TEN, true);

Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(parent.getHash());
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isEqualTo(parent);
assertThat(blocks[0].getTotalDifficulty()).isEqualTo(BigInteger.TEN);
assertThat(blocks[0].isMainChain()).isTrue();
assertThat(blocks[1]).isEqualTo(grandparent);
assertThat(blocks[1].getTotalDifficulty()).isEqualTo(BigInteger.TWO);
assertThat(blocks[1].isMainChain()).isTrue();
assertThat(blocks[2]).isNull();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo() {
Block greatGrandparent = consecutiveBlocks.get(0);
Block grandparent = consecutiveBlocks.get(1);
Block parent = consecutiveBlocks.get(2);

AionBlockStore store = new AionBlockStore(index, blocks, false);
// does not require accurate total difficulty
store.saveBlock(greatGrandparent, BigInteger.ONE, true);
store.saveBlock(grandparent, BigInteger.TWO, true);
store.saveBlock(parent, BigInteger.TEN, true);

Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(parent.getHash());
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isEqualTo(parent);
assertThat(blocks[0].getTotalDifficulty()).isEqualTo(BigInteger.TEN);
assertThat(blocks[0].isMainChain()).isTrue();
assertThat(blocks[1]).isEqualTo(grandparent);
assertThat(blocks[1].getTotalDifficulty()).isEqualTo(BigInteger.TWO);
assertThat(blocks[1].isMainChain()).isTrue();
assertThat(blocks[2]).isEqualTo(greatGrandparent);
assertThat(blocks[2].getTotalDifficulty()).isEqualTo(BigInteger.ONE);
assertThat(blocks[2].isMainChain()).isTrue();
}

@Test
public void testGetThreeGenerationBlocksByHashWithInfo_withSidechains() {
Block greatGrandparent = consecutiveBlocks.get(0);
Block grandparent = consecutiveBlocks.get(1);
Block parent = consecutiveBlocks.get(2);

Block sideGreatGrandparent = spy(greatGrandparent);
byte[] newHash = RandomUtils.nextBytes(32);
when(sideGreatGrandparent.getHash()).thenReturn(newHash);
when(sideGreatGrandparent.getHashWrapper()).thenReturn(ByteArrayWrapper.wrap(newHash));
assertThat(greatGrandparent.getHash()).isNotEqualTo(sideGreatGrandparent.getHash());

Block sideGrandparent = spy(grandparent);
newHash = RandomUtils.nextBytes(32);
when(sideGrandparent.getHash()).thenReturn(newHash);
when(sideGrandparent.getHashWrapper()).thenReturn(ByteArrayWrapper.wrap(newHash));
assertThat(grandparent.getHash()).isNotEqualTo(sideGrandparent.getHash());

Block sideParent = spy(parent);
newHash = RandomUtils.nextBytes(32);
when(sideParent.getHash()).thenReturn(newHash);
when(sideParent.getHashWrapper()).thenReturn(ByteArrayWrapper.wrap(newHash));
assertThat(parent.getHash()).isNotEqualTo(sideParent.getHash());

AionBlockStore store = new AionBlockStore(index, blocks, false);
// does not require accurate total difficulty
store.saveBlock(greatGrandparent, BigInteger.ONE, false);
store.saveBlock(grandparent, BigInteger.TWO, false);
store.saveBlock(parent, BigInteger.TEN, false);
store.saveBlock(sideGreatGrandparent, sideGreatGrandparent.getTotalDifficulty(), true);
store.saveBlock(sideGrandparent, sideGrandparent.getTotalDifficulty(), true);
store.saveBlock(sideParent, sideParent.getTotalDifficulty(), true);

Block[] blocks = store.getThreeGenerationBlocksByHashWithInfo(parent.getHash());
assertThat(blocks.length).isEqualTo(3);
assertThat(blocks[0]).isEqualTo(parent);
assertThat(blocks[0].getHash()).isEqualTo(parent.getHash());
assertThat(blocks[0].getTotalDifficulty()).isEqualTo(BigInteger.TEN);
assertThat(blocks[0].isMainChain()).isFalse();
assertThat(blocks[1]).isEqualTo(grandparent);
assertThat(blocks[1].getHash()).isEqualTo(grandparent.getHash());
assertThat(blocks[1].getTotalDifficulty()).isEqualTo(BigInteger.TWO);
assertThat(blocks[1].isMainChain()).isFalse();
assertThat(blocks[2]).isEqualTo(greatGrandparent);
assertThat(blocks[2].getHash()).isEqualTo(greatGrandparent.getHash());
assertThat(blocks[2].getTotalDifficulty()).isEqualTo(BigInteger.ONE);
assertThat(blocks[2].isMainChain()).isFalse();
}
}

0 comments on commit 3cdd7e3

Please sign in to comment.