-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Interrupt pending transaction processing on block creation timeout #7673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| /* | ||
| * Copyright contributors to Hyperledger Besu. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
| * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations under the License. | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| package org.hyperledger.besu.ethereum.blockcreation.txselection; | ||
|
|
||
| import org.hyperledger.besu.datatypes.Address; | ||
| import org.hyperledger.besu.datatypes.Transaction; | ||
| import org.hyperledger.besu.datatypes.Wei; | ||
| import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; | ||
| import org.hyperledger.besu.evm.frame.MessageFrame; | ||
| import org.hyperledger.besu.evm.log.Log; | ||
| import org.hyperledger.besu.evm.operation.Operation; | ||
| import org.hyperledger.besu.evm.worldstate.WorldView; | ||
| import org.hyperledger.besu.plugin.data.BlockBody; | ||
| import org.hyperledger.besu.plugin.data.BlockHeader; | ||
| import org.hyperledger.besu.plugin.data.ProcessableBlockHeader; | ||
| import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Optional; | ||
| import java.util.Set; | ||
|
|
||
| import org.apache.tuweni.bytes.Bytes; | ||
|
|
||
| public class InterruptibleOperationTracer implements BlockAwareOperationTracer { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just curious, why some methods aren't interruptable still?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I only check for interruption in the methods that are called during the execution of opcodes, since is there where the tx could take too much time, other methods should be more or less constant in time. |
||
| private final BlockAwareOperationTracer delegate; | ||
|
|
||
| public InterruptibleOperationTracer(final BlockAwareOperationTracer delegate) { | ||
| this.delegate = delegate; | ||
| } | ||
|
|
||
| @Override | ||
| public void traceStartBlock(final BlockHeader blockHeader, final BlockBody blockBody) { | ||
| delegate.traceStartBlock(blockHeader, blockBody); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceEndBlock(final BlockHeader blockHeader, final BlockBody blockBody) { | ||
| delegate.traceEndBlock(blockHeader, blockBody); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceStartBlock(final ProcessableBlockHeader processableBlockHeader) { | ||
| delegate.traceStartBlock(processableBlockHeader); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isExtendedTracing() { | ||
| return delegate.isExtendedTracing(); | ||
| } | ||
|
|
||
| @Override | ||
| public void tracePreExecution(final MessageFrame frame) { | ||
| checkInterrupt(); | ||
| delegate.tracePreExecution(frame); | ||
| } | ||
|
|
||
| @Override | ||
| public void tracePostExecution( | ||
| final MessageFrame frame, final Operation.OperationResult operationResult) { | ||
| checkInterrupt(); | ||
| delegate.tracePostExecution(frame, operationResult); | ||
| } | ||
|
|
||
| @Override | ||
| public void tracePrecompileCall( | ||
| final MessageFrame frame, final long gasRequirement, final Bytes output) { | ||
| checkInterrupt(); | ||
| delegate.tracePrecompileCall(frame, gasRequirement, output); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceAccountCreationResult( | ||
| final MessageFrame frame, final Optional<ExceptionalHaltReason> haltReason) { | ||
| checkInterrupt(); | ||
| delegate.traceAccountCreationResult(frame, haltReason); | ||
| } | ||
|
|
||
| @Override | ||
| public void tracePrepareTransaction(final WorldView worldView, final Transaction transaction) { | ||
| delegate.tracePrepareTransaction(worldView, transaction); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceStartTransaction(final WorldView worldView, final Transaction transaction) { | ||
| delegate.traceStartTransaction(worldView, transaction); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceBeforeRewardTransaction( | ||
| final WorldView worldView, final Transaction tx, final Wei miningReward) { | ||
| delegate.traceBeforeRewardTransaction(worldView, tx, miningReward); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceEndTransaction( | ||
| final WorldView worldView, | ||
| final Transaction tx, | ||
| final boolean status, | ||
| final Bytes output, | ||
| final List<Log> logs, | ||
| final long gasUsed, | ||
| final Set<Address> selfDestructs, | ||
| final long timeNs) { | ||
| delegate.traceEndTransaction( | ||
| worldView, tx, status, output, logs, gasUsed, selfDestructs, timeNs); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceContextEnter(final MessageFrame frame) { | ||
| checkInterrupt(); | ||
| delegate.traceContextEnter(frame); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceContextReEnter(final MessageFrame frame) { | ||
| checkInterrupt(); | ||
| delegate.traceContextReEnter(frame); | ||
| } | ||
|
|
||
| @Override | ||
| public void traceContextExit(final MessageFrame frame) { | ||
| checkInterrupt(); | ||
| delegate.traceContextExit(frame); | ||
| } | ||
|
|
||
| private void checkInterrupt() { | ||
| if (Thread.interrupted()) { | ||
| throw new RuntimeException(new InterruptedException("Transaction execution interrupted")); | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment becomes quite complex to read. Can we put this into a method with a clear name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes will rework to make it easier to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have rework it a bit, and added javadoc, hope it is clearer now