use of org.hyperledger.besu.ethereum.chain.MutableBlockchain in project besu by hyperledger.
the class QbftBesuControllerBuilder method createMiningCoordinator.
@Override
protected MiningCoordinator createMiningCoordinator(final ProtocolSchedule protocolSchedule, final ProtocolContext protocolContext, final TransactionPool transactionPool, final MiningParameters miningParameters, final SyncState syncState, final EthProtocolManager ethProtocolManager) {
final MutableBlockchain blockchain = protocolContext.getBlockchain();
final BftExecutors bftExecutors = BftExecutors.create(metricsSystem, BftExecutors.ConsensusType.QBFT);
final Address localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey());
final BftBlockCreatorFactory<?> blockCreatorFactory = new QbftBlockCreatorFactory(transactionPool.getPendingTransactions(), protocolContext, protocolSchedule, qbftForksSchedule, miningParameters, localAddress, bftExtraDataCodec().get());
final ValidatorProvider validatorProvider = protocolContext.getConsensusContext(BftContext.class).getValidatorProvider();
final ProposerSelector proposerSelector = new ProposerSelector(blockchain, bftBlockInterface().get(), true, validatorProvider);
// NOTE: peers should not be used for accessing the network as it does not enforce the
// "only send once" filter applied by the UniqueMessageMulticaster.
peers = new ValidatorPeers(validatorProvider, Istanbul100SubProtocol.NAME);
final UniqueMessageMulticaster uniqueMessageMulticaster = new UniqueMessageMulticaster(peers, qbftConfig.getGossipedHistoryLimit());
final QbftGossip gossiper = new QbftGossip(uniqueMessageMulticaster, bftExtraDataCodec().get());
final BftFinalState finalState = new BftFinalState(validatorProvider, nodeKey, Util.publicKeyToAddress(nodeKey.getPublicKey()), proposerSelector, uniqueMessageMulticaster, new RoundTimer(bftEventQueue, qbftConfig.getRequestTimeoutSeconds(), bftExecutors), new BlockTimer(bftEventQueue, qbftForksSchedule, bftExecutors, clock), blockCreatorFactory, clock);
final MessageValidatorFactory messageValidatorFactory = new MessageValidatorFactory(proposerSelector, protocolSchedule, protocolContext, bftExtraDataCodec().get());
final Subscribers<MinedBlockObserver> minedBlockObservers = Subscribers.create();
minedBlockObservers.subscribe(ethProtocolManager);
minedBlockObservers.subscribe(blockLogger(transactionPool, localAddress));
final FutureMessageBuffer futureMessageBuffer = new FutureMessageBuffer(qbftConfig.getFutureMessagesMaxDistance(), qbftConfig.getFutureMessagesLimit(), blockchain.getChainHeadBlockNumber());
final MessageTracker duplicateMessageTracker = new MessageTracker(qbftConfig.getDuplicateMessageLimit());
final MessageFactory messageFactory = new MessageFactory(nodeKey);
final BftEventHandler qbftController = new QbftController(blockchain, finalState, new QbftBlockHeightManagerFactory(finalState, new QbftRoundFactory(finalState, protocolContext, protocolSchedule, minedBlockObservers, messageValidatorFactory, messageFactory, bftExtraDataCodec().get()), messageValidatorFactory, messageFactory, new ValidatorModeTransitionLogger(qbftForksSchedule)), gossiper, duplicateMessageTracker, futureMessageBuffer, new EthSynchronizerUpdater(ethProtocolManager.ethContext().getEthPeers()), bftExtraDataCodec().get());
final EventMultiplexer eventMultiplexer = new EventMultiplexer(qbftController);
final BftProcessor bftProcessor = new BftProcessor(bftEventQueue, eventMultiplexer);
final MiningCoordinator miningCoordinator = new BftMiningCoordinator(bftExecutors, qbftController, bftProcessor, blockCreatorFactory, blockchain, bftEventQueue);
miningCoordinator.enable();
return miningCoordinator;
}
use of org.hyperledger.besu.ethereum.chain.MutableBlockchain in project besu by hyperledger.
the class RestoreState method restoreBlocks.
private void restoreBlocks() throws IOException {
try (final RollingFileReader headerReader = new RollingFileReader(this::headerFileName, compressed);
final RollingFileReader bodyReader = new RollingFileReader(this::bodyFileName, compressed);
final RollingFileReader receiptReader = new RollingFileReader(this::receiptFileName, compressed)) {
final MutableBlockchain blockchain = besuController.getProtocolContext().getBlockchain();
// target block is "including" the target block, so LE test not LT.
for (long i = 0; i <= targetBlock; i++) {
if (i % 100000 == 0) {
LOG.info("Loading chain data {} / {}", i, targetBlock);
}
final byte[] headerEntry = headerReader.readBytes();
final byte[] bodyEntry = bodyReader.readBytes();
final byte[] receiptEntry = receiptReader.readBytes();
final BlockHeaderFunctions functions = new MainnetBlockHeaderFunctions();
final BlockHeader header = BlockHeader.readFrom(new BytesValueRLPInput(Bytes.wrap(headerEntry), false, true), functions);
final BlockBody body = BlockBody.readFrom(new BytesValueRLPInput(Bytes.wrap(bodyEntry), false, true), functions);
final RLPInput receiptsRlp = new BytesValueRLPInput(Bytes.wrap(receiptEntry), false, true);
final int receiptsCount = receiptsRlp.enterList();
final List<TransactionReceipt> receipts = new ArrayList<>(receiptsCount);
for (int j = 0; j < receiptsCount; j++) {
receipts.add(TransactionReceipt.readFrom(receiptsRlp, true));
}
receiptsRlp.leaveList();
blockchain.appendBlock(new Block(header, body), receipts);
}
}
LOG.info("Chain data loaded");
}
use of org.hyperledger.besu.ethereum.chain.MutableBlockchain in project besu by hyperledger.
the class TransactionSmartContractPermissioningControllerTest method setupController.
private TransactionSmartContractPermissioningController setupController(final String resourceName, final String contractAddressString) throws IOException {
final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET;
final String emptyContractFile = Resources.toString(this.getClass().getResource(resourceName), UTF_8);
final GenesisState genesisState = GenesisState.fromConfig(GenesisConfigFile.fromConfig(emptyContractFile), protocolSchedule);
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
final WorldStateArchive worldArchive = createInMemoryWorldStateArchive();
genesisState.writeStateTo(worldArchive.getMutable());
final TransactionSimulator ts = new TransactionSimulator(blockchain, worldArchive, protocolSchedule);
final Address contractAddress = Address.fromHexString(contractAddressString);
when(metricsSystem.createCounter(BesuMetricCategory.PERMISSIONING, "transaction_smart_contract_check_count", "Number of times the transaction smart contract permissioning provider has been checked")).thenReturn(checkCounter);
when(metricsSystem.createCounter(BesuMetricCategory.PERMISSIONING, "transaction_smart_contract_check_count_permitted", "Number of times the transaction smart contract permissioning provider has been checked and returned permitted")).thenReturn(checkPermittedCounter);
when(metricsSystem.createCounter(BesuMetricCategory.PERMISSIONING, "transaction_smart_contract_check_count_unpermitted", "Number of times the transaction smart contract permissioning provider has been checked and returned unpermitted")).thenReturn(checkUnpermittedCounter);
return new TransactionSmartContractPermissioningController(contractAddress, ts, metricsSystem);
}
use of org.hyperledger.besu.ethereum.chain.MutableBlockchain in project besu by hyperledger.
the class BlockchainReferenceTestTools method executeTest.
public static void executeTest(final BlockchainReferenceTestCaseSpec spec) {
final BlockHeader genesisBlockHeader = spec.getGenesisBlockHeader();
final MutableWorldState worldState = spec.getWorldStateArchive().getMutable(genesisBlockHeader.getStateRoot(), genesisBlockHeader.getHash()).get();
assertThat(worldState.rootHash()).isEqualTo(genesisBlockHeader.getStateRoot());
final ProtocolSchedule schedule = REFERENCE_TEST_PROTOCOL_SCHEDULES.getByName(spec.getNetwork());
final MutableBlockchain blockchain = spec.getBlockchain();
final ProtocolContext context = spec.getProtocolContext();
for (final BlockchainReferenceTestCaseSpec.CandidateBlock candidateBlock : spec.getCandidateBlocks()) {
if (!candidateBlock.isExecutable()) {
return;
}
try {
final Block block = candidateBlock.getBlock();
final ProtocolSpec protocolSpec = schedule.getByBlockNumber(block.getHeader().getNumber());
final BlockImporter blockImporter = protocolSpec.getBlockImporter();
final HeaderValidationMode validationMode = "NoProof".equalsIgnoreCase(spec.getSealEngine()) ? HeaderValidationMode.LIGHT : HeaderValidationMode.FULL;
final boolean imported = blockImporter.importBlock(context, block, validationMode, validationMode);
assertThat(imported).isEqualTo(candidateBlock.isValid());
} catch (final RLPException e) {
assertThat(candidateBlock.isValid()).isFalse();
}
}
Assertions.assertThat(blockchain.getChainHeadHash()).isEqualTo(spec.getLastBlockHash());
}
use of org.hyperledger.besu.ethereum.chain.MutableBlockchain in project besu by hyperledger.
the class MergeCoordinator method updateForkChoice.
@Override
public ForkchoiceResult updateForkChoice(final BlockHeader newHead, final Hash finalizedBlockHash, final Hash safeBlockHash) {
MutableBlockchain blockchain = protocolContext.getBlockchain();
Optional<BlockHeader> currentFinalized = mergeContext.getFinalized();
final Optional<BlockHeader> newFinalized = blockchain.getBlockHeader(finalizedBlockHash);
final Optional<Hash> latestValid = getLatestValidAncestor(newHead);
if (currentFinalized.isPresent() && newFinalized.isPresent() && !isDescendantOf(currentFinalized.get(), newFinalized.get())) {
return ForkchoiceResult.withFailure(String.format("new finalized block %s is not a descendant of current finalized block %s", finalizedBlockHash, currentFinalized.get().getBlockHash()), latestValid);
}
// ensure new head is descendant of finalized
Optional<String> descendantError = newFinalized.map(Optional::of).orElse(currentFinalized).filter(finalized -> !isDescendantOf(finalized, newHead)).map(finalized -> String.format("new head block %s is not a descendant of current finalized block %s", newHead.getBlockHash(), finalized.getBlockHash()));
if (descendantError.isPresent()) {
return ForkchoiceResult.withFailure(descendantError.get(), latestValid);
}
Optional<BlockHeader> parentOfNewHead = blockchain.getBlockHeader(newHead.getParentHash());
if (parentOfNewHead.isPresent() && parentOfNewHead.get().getTimestamp() >= newHead.getTimestamp()) {
return ForkchoiceResult.withFailure("new head timestamp not greater than parent", latestValid);
}
// set the new head
blockchain.rewindToBlock(newHead.getHash());
// set and persist the new finalized block if it is present
newFinalized.ifPresent(blockHeader -> {
blockchain.setFinalized(blockHeader.getHash());
mergeContext.setFinalized(blockHeader);
});
blockchain.getBlockHeader(safeBlockHash).ifPresent(newSafeBlock -> {
blockchain.setSafeBlock(safeBlockHash);
mergeContext.setSafeBlock(newSafeBlock);
});
return ForkchoiceResult.withResult(newFinalized, Optional.of(newHead));
}
Aggregations