mirror of https://github.com/hyperledger/besu
[MINOR] Revert "[MINOR] Parameterize BlockchainUtilTest " (#55)
* Revert "[MINOR] Parameterize BlockchainUtilTest (#7)"
This reverts commit daad2995a7
.
* Update PantheonInfo.java
parent
76c742eba1
commit
92fefe60e5
@ -1,52 +0,0 @@ |
|||||||
package net.consensys.pantheon.ethereum.util; |
|
||||||
|
|
||||||
import tech.pegasys.pantheon.ethereum.chain.Blockchain; |
|
||||||
import tech.pegasys.pantheon.ethereum.core.BlockHeader; |
|
||||||
|
|
||||||
import java.util.Collections; |
|
||||||
import java.util.Comparator; |
|
||||||
import java.util.List; |
|
||||||
import java.util.OptionalInt; |
|
||||||
|
|
||||||
public class BlockchainUtil { |
|
||||||
|
|
||||||
private BlockchainUtil() {} |
|
||||||
|
|
||||||
/** |
|
||||||
* General purpose utility to process a list of headers and a blockchain, sussing out which header |
|
||||||
* in the input list is simultaneously the highest order block number and a direct match with one |
|
||||||
* of the headers of the local chain. The point being to determine the point of departure in fork |
|
||||||
* situations. |
|
||||||
* |
|
||||||
* @param blockchain our local copy of the blockchain |
|
||||||
* @param headers the list of remote headers |
|
||||||
* @param ascendingHeaderOrder whether the headers are sorted in ascending or descending order |
|
||||||
* @return index of the highest known header, or an empty value if no header is known |
|
||||||
*/ |
|
||||||
public static OptionalInt findHighestKnownBlockIndex( |
|
||||||
final Blockchain blockchain, |
|
||||||
final List<BlockHeader> headers, |
|
||||||
final boolean ascendingHeaderOrder) { |
|
||||||
int offset = ascendingHeaderOrder ? -1 : 0; |
|
||||||
Comparator<BlockHeader> comparator = knownBlockComparator(blockchain, ascendingHeaderOrder); |
|
||||||
|
|
||||||
int insertionIndex = -Collections.binarySearch(headers, null, comparator) - 1; |
|
||||||
int ancestorIndex = insertionIndex + offset; |
|
||||||
if (ancestorIndex < 0 || ancestorIndex >= headers.size()) { |
|
||||||
return OptionalInt.empty(); |
|
||||||
} |
|
||||||
return OptionalInt.of(ancestorIndex); |
|
||||||
} |
|
||||||
|
|
||||||
private static Comparator<BlockHeader> knownBlockComparator( |
|
||||||
final Blockchain blockchain, final boolean ascendingHeaderOrder) { |
|
||||||
Comparator<BlockHeader> comparator = |
|
||||||
(final BlockHeader element0, final BlockHeader element1) -> { |
|
||||||
if (element0 == null) { |
|
||||||
return blockchain.contains(element1.getHash()) ? -1 : 1; |
|
||||||
} |
|
||||||
return blockchain.contains(element0.getHash()) ? 1 : -1; |
|
||||||
}; |
|
||||||
return ascendingHeaderOrder ? comparator.reversed() : comparator; |
|
||||||
} |
|
||||||
} |
|
@ -1,135 +0,0 @@ |
|||||||
package net.consensys.pantheon.ethereum.util; |
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||||
|
|
||||||
import tech.pegasys.pantheon.ethereum.core.Block; |
|
||||||
import tech.pegasys.pantheon.ethereum.core.BlockBody; |
|
||||||
import tech.pegasys.pantheon.ethereum.core.BlockHeader; |
|
||||||
import tech.pegasys.pantheon.ethereum.core.TransactionReceipt; |
|
||||||
import tech.pegasys.pantheon.ethereum.db.DefaultMutableBlockchain; |
|
||||||
import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockHashFunction; |
|
||||||
import tech.pegasys.pantheon.ethereum.testutil.BlockDataGenerator; |
|
||||||
import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage; |
|
||||||
import tech.pegasys.pantheon.services.kvstore.KeyValueStorage; |
|
||||||
import tech.pegasys.pantheon.util.uint.UInt256; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.List; |
|
||||||
import java.util.OptionalInt; |
|
||||||
import java.util.Random; |
|
||||||
|
|
||||||
import org.junit.Before; |
|
||||||
import org.junit.BeforeClass; |
|
||||||
import org.junit.Test; |
|
||||||
import org.junit.runner.RunWith; |
|
||||||
import org.junit.runners.Parameterized; |
|
||||||
|
|
||||||
@RunWith(Parameterized.class) |
|
||||||
public class BlockchainUtilParameterizedTest { |
|
||||||
private static final BlockDataGenerator blockDataGenerator = new BlockDataGenerator(); |
|
||||||
private static final Random random = new Random(1337); |
|
||||||
|
|
||||||
private static final int chainHeight = 89; |
|
||||||
private final int commonAncestorHeight; |
|
||||||
private static Block genesisBlock; |
|
||||||
private static KeyValueStorage localKvStore; |
|
||||||
private static DefaultMutableBlockchain localBlockchain; |
|
||||||
|
|
||||||
private KeyValueStorage remoteKvStore; |
|
||||||
private DefaultMutableBlockchain remoteBlockchain; |
|
||||||
|
|
||||||
private BlockHeader commonHeader; |
|
||||||
private List<BlockHeader> headers; |
|
||||||
|
|
||||||
public BlockchainUtilParameterizedTest(final int commonAncestorHeight) { |
|
||||||
this.commonAncestorHeight = commonAncestorHeight; |
|
||||||
} |
|
||||||
|
|
||||||
@BeforeClass |
|
||||||
public static void setupClass() { |
|
||||||
genesisBlock = blockDataGenerator.genesisBlock(); |
|
||||||
localKvStore = new InMemoryKeyValueStorage(); |
|
||||||
localBlockchain = |
|
||||||
new DefaultMutableBlockchain( |
|
||||||
genesisBlock, localKvStore, MainnetBlockHashFunction::createHash); |
|
||||||
// Setup local chain.
|
|
||||||
for (int i = 1; i <= chainHeight; i++) { |
|
||||||
final BlockDataGenerator.BlockOptions options = |
|
||||||
new BlockDataGenerator.BlockOptions() |
|
||||||
.setBlockNumber(i) |
|
||||||
.setParentHash(localBlockchain.getBlockHashByNumber(i - 1).get()); |
|
||||||
final Block block = blockDataGenerator.block(options); |
|
||||||
final List<TransactionReceipt> receipts = blockDataGenerator.receipts(block); |
|
||||||
localBlockchain.appendBlock(block, receipts); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Before |
|
||||||
public void setup() { |
|
||||||
remoteKvStore = new InMemoryKeyValueStorage(); |
|
||||||
remoteBlockchain = |
|
||||||
new DefaultMutableBlockchain( |
|
||||||
genesisBlock, remoteKvStore, MainnetBlockHashFunction::createHash); |
|
||||||
|
|
||||||
commonHeader = genesisBlock.getHeader(); |
|
||||||
for (long i = 1; i <= commonAncestorHeight; i++) { |
|
||||||
commonHeader = localBlockchain.getBlockHeader(i).get(); |
|
||||||
final List<TransactionReceipt> receipts = |
|
||||||
localBlockchain.getTxReceipts(commonHeader.getHash()).get(); |
|
||||||
final BlockBody commonBody = localBlockchain.getBlockBody(commonHeader.getHash()).get(); |
|
||||||
remoteBlockchain.appendBlock(new Block(commonHeader, commonBody), receipts); |
|
||||||
} |
|
||||||
// Remaining blocks are disparate.
|
|
||||||
for (long i = commonAncestorHeight + 1L; i <= chainHeight; i++) { |
|
||||||
final BlockDataGenerator.BlockOptions localOptions = |
|
||||||
new BlockDataGenerator.BlockOptions() |
|
||||||
.setBlockNumber(i) |
|
||||||
.setParentHash(localBlockchain.getBlockHashByNumber(i - 1).get()); |
|
||||||
final Block localBlock = blockDataGenerator.block(localOptions); |
|
||||||
final List<TransactionReceipt> localReceipts = blockDataGenerator.receipts(localBlock); |
|
||||||
localBlockchain.appendBlock(localBlock, localReceipts); |
|
||||||
|
|
||||||
final BlockDataGenerator.BlockOptions remoteOptions = |
|
||||||
new BlockDataGenerator.BlockOptions() |
|
||||||
.setDifficulty(UInt256.ONE) // differentiator
|
|
||||||
.setBlockNumber(i) |
|
||||||
.setParentHash(remoteBlockchain.getBlockHashByNumber(i - 1).get()); |
|
||||||
final Block remoteBlock = blockDataGenerator.block(remoteOptions); |
|
||||||
final List<TransactionReceipt> remoteReceipts = blockDataGenerator.receipts(remoteBlock); |
|
||||||
remoteBlockchain.appendBlock(remoteBlock, remoteReceipts); |
|
||||||
} |
|
||||||
headers = new ArrayList<>(); |
|
||||||
for (long i = 0L; i <= remoteBlockchain.getChainHeadBlockNumber(); i++) { |
|
||||||
headers.add(remoteBlockchain.getBlockHeader(i).get()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "commonAncestor={0}") |
|
||||||
public static Collection<Object[]> parameters() { |
|
||||||
final List<Object[]> params = new ArrayList<>(); |
|
||||||
params.add(new Object[] {0}); |
|
||||||
params.add(new Object[] {chainHeight}); |
|
||||||
params.add(new Object[] {random.nextInt(chainHeight - 1) + 1}); |
|
||||||
params.add(new Object[] {random.nextInt(chainHeight - 1) + 1}); |
|
||||||
params.add(new Object[] {random.nextInt(chainHeight - 1) + 1}); |
|
||||||
return params; |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void searchesAscending() { |
|
||||||
OptionalInt maybeAncestorNumber = |
|
||||||
BlockchainUtil.findHighestKnownBlockIndex(localBlockchain, headers, true); |
|
||||||
assertThat(maybeAncestorNumber.getAsInt()).isEqualTo(Math.toIntExact(commonHeader.getNumber())); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void searchesDescending() { |
|
||||||
Collections.reverse(headers); |
|
||||||
OptionalInt maybeAncestorNumber = |
|
||||||
BlockchainUtil.findHighestKnownBlockIndex(localBlockchain, headers, false); |
|
||||||
assertThat(maybeAncestorNumber.getAsInt()) |
|
||||||
.isEqualTo(Math.toIntExact(chainHeight - commonHeader.getNumber())); |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue