diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a9a2a4ead..6122cd3bbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 24.2.1-SNAPSHOT + +### Breaking Changes + +### Deprecations + +### Additions and Improvements +- Extend `Blockchain` service [#6592](https://github.com/hyperledger/besu/pull/6592) + +### Bug fixes + ## 24.2.0-SNAPSHOT ### Breaking Changes diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index f4b08e4f68..bcb0ce6857 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -373,6 +373,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final TransactionSelectionServiceImpl transactionSelectionServiceImpl; private final PluginTransactionValidatorServiceImpl transactionValidatorServiceImpl; + private final BlockchainServiceImpl blockchainServiceImpl; static class P2PDiscoveryOptionGroup { @@ -957,7 +958,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { new PkiBlockCreationConfigurationProvider(), new RpcEndpointServiceImpl(), new TransactionSelectionServiceImpl(), - new PluginTransactionValidatorServiceImpl()); + new PluginTransactionValidatorServiceImpl(), + new BlockchainServiceImpl()); } /** @@ -979,6 +981,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * @param rpcEndpointServiceImpl instance of RpcEndpointServiceImpl * @param transactionSelectionServiceImpl instance of TransactionSelectionServiceImpl * @param transactionValidatorServiceImpl instance of TransactionValidatorServiceImpl + * @param blockchainServiceImpl instance of BlockchainServiceImpl */ @VisibleForTesting protected BesuCommand( @@ -997,7 +1000,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider, final RpcEndpointServiceImpl rpcEndpointServiceImpl, final TransactionSelectionServiceImpl transactionSelectionServiceImpl, - final PluginTransactionValidatorServiceImpl transactionValidatorServiceImpl) { + final PluginTransactionValidatorServiceImpl transactionValidatorServiceImpl, + final BlockchainServiceImpl blockchainServiceImpl) { this.besuComponent = besuComponent; this.logger = besuComponent.getBesuCommandLogger(); this.rlpBlockImporter = rlpBlockImporter; @@ -1017,6 +1021,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.rpcEndpointServiceImpl = rpcEndpointServiceImpl; this.transactionSelectionServiceImpl = transactionSelectionServiceImpl; this.transactionValidatorServiceImpl = transactionValidatorServiceImpl; + this.blockchainServiceImpl = blockchainServiceImpl; } /** @@ -1208,6 +1213,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { TransactionSelectionService.class, transactionSelectionServiceImpl); besuPluginContext.addService( PluginTransactionValidatorService.class, transactionValidatorServiceImpl); + besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl); // register built-in plugins rocksDBPlugin = new RocksDBPlugin(); @@ -1288,6 +1294,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } private void startPlugins() { + blockchainServiceImpl.init( + besuController.getProtocolContext(), besuController.getProtocolSchedule()); + besuPluginContext.addService( BesuEvents.class, new BesuEventsImpl( @@ -1297,10 +1306,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { besuController.getSyncState())); besuPluginContext.addService(MetricsSystem.class, getMetricsSystem()); - besuPluginContext.addService( - BlockchainService.class, - new BlockchainServiceImpl(besuController.getProtocolContext().getBlockchain())); - besuPluginContext.addService( TraceService.class, new TraceServiceImpl( diff --git a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java index a3b37a6665..aa1c6a2128 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BlockchainServiceImpl.java @@ -15,8 +15,13 @@ package org.hyperledger.besu.services; -import org.hyperledger.besu.ethereum.chain.Blockchain; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.BlockBody; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.data.BlockContext; import org.hyperledger.besu.plugin.data.BlockHeader; @@ -29,15 +34,21 @@ import java.util.function.Supplier; @Unstable public class BlockchainServiceImpl implements BlockchainService { - private final Blockchain blockchain; + private ProtocolContext protocolContext; + private ProtocolSchedule protocolSchedule; + + /** Create a new instance */ + public BlockchainServiceImpl() {} /** * Instantiates a new Blockchain service. * - * @param blockchain the blockchain + * @param protocolContext the protocol context + * @param protocolSchedule the protocol schedule */ - public BlockchainServiceImpl(final Blockchain blockchain) { - this.blockchain = blockchain; + public void init(final ProtocolContext protocolContext, final ProtocolSchedule protocolSchedule) { + this.protocolContext = protocolContext; + this.protocolSchedule = protocolSchedule; } /** @@ -48,11 +59,39 @@ public class BlockchainServiceImpl implements BlockchainService { */ @Override public Optional getBlockByNumber(final long number) { - return blockchain + return protocolContext + .getBlockchain() .getBlockByNumber(number) .map(block -> blockContext(block::getHeader, block::getBody)); } + @Override + public Hash getChainHeadHash() { + return protocolContext.getBlockchain().getChainHeadHash(); + } + + @Override + public BlockHeader getChainHeadHeader() { + return protocolContext.getBlockchain().getChainHeadHeader(); + } + + @Override + public Optional getNextBlockBaseFee() { + final var chainHeadHeader = protocolContext.getBlockchain().getChainHeadHeader(); + final var protocolSpec = + protocolSchedule.getForNextBlockHeader(chainHeadHeader, System.currentTimeMillis()); + return Optional.of(protocolSpec.getFeeMarket()) + .filter(FeeMarket::implementsBaseFee) + .map(BaseFeeMarket.class::cast) + .map( + feeMarket -> + feeMarket.computeBaseFee( + chainHeadHeader.getNumber() + 1, + chainHeadHeader.getBaseFee().orElse(Wei.ZERO), + chainHeadHeader.getGasUsed(), + feeMarket.targetGasUsed(chainHeadHeader))); + } + private static BlockContext blockContext( final Supplier blockHeaderSupplier, final Supplier blockBodySupplier) { diff --git a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java index 34c9d44e0f..331f7d54a9 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -83,6 +83,7 @@ import org.hyperledger.besu.plugin.services.storage.PrivacyKeyValueStorageFactor import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier; import org.hyperledger.besu.services.BesuConfigurationImpl; import org.hyperledger.besu.services.BesuPluginContextImpl; +import org.hyperledger.besu.services.BlockchainServiceImpl; import org.hyperledger.besu.services.PermissioningServiceImpl; import org.hyperledger.besu.services.PluginTransactionValidatorServiceImpl; import org.hyperledger.besu.services.PrivacyPluginServiceImpl; @@ -564,7 +565,8 @@ public abstract class CommandTestAbstract { pkiBlockCreationConfigProvider, rpcEndpointServiceImpl, new TransactionSelectionServiceImpl(), - new PluginTransactionValidatorServiceImpl()); + new PluginTransactionValidatorServiceImpl(), + new BlockchainServiceImpl()); } @Override diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 9184bb5706..46611fc29d 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -69,7 +69,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = 'f6P3+XG9GjPYEg7zrXHlujoE2/4axgd+EjKGDDJVVp8=' + knownHash = 'Pi7Veo9W9kmjDJJNB89UTUXbYyRmoN6osK/tD163h3E=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java index e9356ae76e..76f66aba6c 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/services/BlockchainService.java @@ -14,8 +14,11 @@ */ package org.hyperledger.besu.plugin.services; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.plugin.Unstable; import org.hyperledger.besu.plugin.data.BlockContext; +import org.hyperledger.besu.plugin.data.BlockHeader; import java.util.Optional; @@ -29,4 +32,25 @@ public interface BlockchainService extends BesuService { * @return the BlockContext */ Optional getBlockByNumber(final long number); + + /** + * Get the hash of the chain head + * + * @return chain head hash + */ + Hash getChainHeadHash(); + + /** + * Get the block header of the chain head + * + * @return chain head block header + */ + BlockHeader getChainHeadHeader(); + + /** + * Return the base fee for the next block + * + * @return base fee of the next block or empty if the fee market does not support base fee + */ + Optional getNextBlockBaseFee(); }