Log receipts reorg (#4497)

* re-emits correct block added event when reminding
* uprevs version of log bloom cache metadata to force regeneration on startup

Signed-off-by: Justin Florentine <justin+github@florentine.us>
pull/4499/head
Justin Florentine 2 years ago committed by GitHub
parent 2bcd2a7eec
commit 6b31efa0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 57
      consensus/merge/src/test/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinatorTest.java
  3. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/cache/LogBloomCacheMetadata.java
  4. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/DefaultBlockchain.java

@ -9,9 +9,11 @@
### Additions and Improvements
### Bug Fixes
- Corrects emission of blockadded events when rewinding during a re-org. Fix for [#4495](https://github.com/hyperledger/besu/issues/4495)
-
### Download Links
## 22.10.0-RC1
### Additions and Improvements

@ -41,6 +41,9 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BlockAddedEvent;
import org.hyperledger.besu.ethereum.chain.BlockAddedEvent.EventType;
import org.hyperledger.besu.ethereum.chain.BlockAddedObserver;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.Block;
@ -68,6 +71,7 @@ import java.time.ZoneId;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import com.google.common.base.Suppliers;
@ -80,6 +84,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RunWith(MockitoJUnitRunner.class)
public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
@ -87,6 +93,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
private static final com.google.common.base.Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
private static final Logger LOG = LoggerFactory.getLogger(MergeCoordinatorTest.class);
private static final SECPPrivateKey PRIVATE_KEY1 =
SIGNATURE_ALGORITHM
.get()
@ -350,6 +357,55 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
verify(mergeContext).setSafeBlock(firstFinalizedHeader);
}
@Test
public void reorgAroundLogBloomCacheUpdate() {
// generate 5 blocks, remember them in order, all need to be parented correctly.
BlockHeader prevParent = genesisState.getBlock().getHeader();
AtomicReference<BlockAddedEvent> lastBlockAddedEvent = new AtomicReference<>();
blockchain.observeBlockAdded(
new BlockAddedObserver() {
@Override
public void onBlockAdded(final BlockAddedEvent event) {
LOG.info(event.toString());
lastBlockAddedEvent.set(event);
}
});
for (int i = 0; i <= 5; i++) {
BlockHeader nextBlock =
nextBlockHeader(
prevParent, genesisState.getBlock().getHeader().getTimestamp() + i * 1000);
coordinator.rememberBlock(new Block(nextBlock, BlockBody.empty()));
prevParent = nextBlock;
}
coordinator.updateForkChoice(
prevParent,
genesisState.getBlock().getHash(),
genesisState.getBlock().getHash(),
Optional.empty());
Hash expectedCommonAncestor = blockchain.getBlockHeader(2).get().getBlockHash();
// generate from 3' down to some other head. Remeber those.
BlockHeader forkPoint = blockchain.getBlockHeader(2).get();
prevParent = forkPoint;
for (int i = 3; i <= 5; i++) {
BlockHeader nextPrime =
nextBlockHeader(
prevParent, genesisState.getBlock().getHeader().getTimestamp() + i * 1001);
coordinator.rememberBlock(new Block(nextPrime, BlockBody.empty()));
prevParent = nextPrime;
}
coordinator.updateForkChoice(
prevParent,
genesisState.getBlock().getHash(),
genesisState.getBlock().getHash(),
Optional.empty());
assertThat(lastBlockAddedEvent.get().getCommonAncestorHash()).isEqualTo(expectedCommonAncestor);
assertThat(lastBlockAddedEvent.get().getEventType()).isEqualTo(EventType.CHAIN_REORG);
assertThat(lastBlockAddedEvent.get().getBlock().getHash()).isEqualTo(prevParent.getBlockHash());
}
@Test
public void updateForkChoiceShouldPersistLastFinalizedBlockHash() {
BlockHeader terminalHeader = terminalPowBlock();
@ -649,6 +705,7 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
private BlockHeader nextBlockHeader(
final BlockHeader parentHeader, final long... optionalTimestamp) {
return headerGenerator
.difficulty(Difficulty.ZERO)
.parentHash(parentHeader.getHash())

@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
public class LogBloomCacheMetadata {
private static final Logger LOG = LoggerFactory.getLogger(LogBloomCacheMetadata.class);
public static final int DEFAULT_VERSION = 2;
public static final int DEFAULT_VERSION = 3;
private static final String METADATA_FILENAME = "CACHE_METADATA.json";
private static final ObjectMapper MAPPER = new ObjectMapper();

@ -576,8 +576,9 @@ public class DefaultBlockchain implements MutableBlockchain {
final BlockWithReceipts blockWithReceipts = getBlockWithReceipts(oldBlockHeader).get();
final Block block = blockWithReceipts.getBlock();
handleChainReorg(updater, blockWithReceipts);
var reorgEvent = handleChainReorg(updater, blockWithReceipts);
updater.commit();
blockAddedObservers.forEach(o -> o.onBlockAdded(reorgEvent));
updateCacheForNewCanonicalHead(block, calculateTotalDifficulty(block.getHeader()));
return true;

Loading…
Cancel
Save