Skip to content
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

chore: Support custom Set<Operation> in standalone executor #17329

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hedera-node/hedera-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ testModuleInfo {
requires("org.junit.jupiter.params")
requires("org.mockito")
requires("org.mockito.junit.jupiter")
requires("tuweni.bytes")
requires("uk.org.webcompere.systemstubs.core")
requires("uk.org.webcompere.systemstubs.jupiter")
requiresStatic("com.github.spotbugs.annotations")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.hedera.node.app.service.token.impl.handlers.BaseCryptoHandler.asAccount;
import static com.hedera.node.app.spi.AppContext.Gossip.UNAVAILABLE_GOSSIP;
import static com.hedera.node.app.workflows.standalone.impl.NoopVerificationStrategies.NOOP_VERIFICATION_STRATEGIES;
import static java.util.Objects.requireNonNull;

import com.hedera.node.app.Hedera;
import com.hedera.node.app.config.BootstrapConfigProviderImpl;
Expand All @@ -44,11 +45,15 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.time.InstantSource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.tracing.OperationTracer;

/**
Expand All @@ -67,21 +72,147 @@
void runWhere(@NonNull List<OperationTracer> tracers, @NonNull Runnable runnable);
}

/**
* The properties to use when creating a new {@link TransactionExecutor}.
* @param state the {@link State} to use
* @param appProperties the properties to use
* @param customTracerBinding the custom tracer binding to use
* @param customOps the custom operations to use
*/
public record Properties(
@NonNull State state,
@NonNull Map<String, String> appProperties,
@Nullable TracerBinding customTracerBinding,
@NonNull Set<Operation> customOps) {
/**
* Create a new {@link Builder} instance.
* @return a new {@link Builder} instance
*/
public static Builder newBuilder() {
return new Builder();
}

/**
* Builder for {@link Properties}.
*/
public static class Builder {
private State state;
private TracerBinding customTracerBinding;
private final Map<String, String> appProperties = new HashMap<>();
private final Set<Operation> customOps = new HashSet<>();

/**
* Set the required {@link State} field.
*/
public Builder state(@NonNull final State state) {
this.state = requireNonNull(state);
return this;
}

/**
* Add or override a single property.
*/
public Builder appProperty(@NonNull final String key, @NonNull final String value) {
requireNonNull(key);
requireNonNull(value);
this.appProperties.put(key, value);
return this;
}

/**
* Add/override multiple properties at once.
*/
public Builder appProperties(@NonNull final Map<String, String> properties) {
requireNonNull(properties);
this.appProperties.putAll(properties);
return this;
}

/**
* Set the optional {@link TracerBinding}.
*/
public Builder customTracerBinding(@Nullable final TracerBinding customTracerBinding) {
this.customTracerBinding = customTracerBinding;
return this;
}

/**
* Set the custom operations in bulk.
*/
public Builder customOps(@NonNull final Set<? extends Operation> customOps) {
requireNonNull(customOps);
this.customOps.addAll(customOps);
return this;
}

/**
* Add a single custom operation.
*/
public Builder addCustomOp(@NonNull final Operation customOp) {
tinker-michaelj marked this conversation as resolved.
Show resolved Hide resolved
requireNonNull(customOp);
this.customOps.add(customOp);
return this;
}

/**
* Build and return the immutable {@link Properties} record.
*/
public Properties build() {
if (state == null) {
throw new IllegalStateException("State must not be null");
}
return new Properties(state, Map.copyOf(appProperties), customTracerBinding, Set.copyOf(customOps));
}
}
}

/**
* Creates a new {@link TransactionExecutor} based on the given {@link State} and properties.
* @param properties the properties to use for the executor
* @return a new {@link TransactionExecutor}
*/
public TransactionExecutor newExecutor(@NonNull final Properties properties) {
requireNonNull(properties);
return newExecutor(
properties.state(),
properties.appProperties(),
properties.customTracerBinding(),
properties.customOps());
}

/**
* Creates a new {@link TransactionExecutor} based on the given {@link State} and properties.
* Prefer
*
* @param state the {@link State} to create the executor from
* @param properties the properties to use for the executor
* @param customTracerBinding if not null, the tracer binding to use
* @return a new {@link TransactionExecutor}
*/
@Deprecated(since = "0.58")
public TransactionExecutor newExecutor(
@NonNull final State state,
@NonNull final Map<String, String> properties,
@Nullable final TracerBinding customTracerBinding) {
return newExecutor(state, properties, customTracerBinding, Set.of());

Check warning on line 197 in hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/standalone/TransactionExecutors.java

View check run for this annotation

Codecov / codecov/patch

hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/standalone/TransactionExecutors.java#L197

Added line #L197 was not covered by tests
}

/**
* Creates a new {@link TransactionExecutor}.
* @param state the {@link State} to use
* @param properties the properties to use
* @param customTracerBinding the custom tracer binding to use
* @param customOps the custom operations to use
* @return a new {@link TransactionExecutor}
*/
private TransactionExecutor newExecutor(
@NonNull final State state,
@NonNull final Map<String, String> properties,
@Nullable final TracerBinding customTracerBinding,
@NonNull final Set<Operation> customOps) {
final var tracerBinding =
customTracerBinding != null ? customTracerBinding : DefaultTracerBinding.DEFAULT_TRACER_BINDING;
final var executor = newExecutorComponent(state, properties, tracerBinding);
final var executor = newExecutorComponent(state, properties, tracerBinding, customOps);
executor.initializer().accept(state);
executor.stateNetworkInfo().initFrom(state);
final var exchangeRateManager = executor.exchangeRateManager();
Expand All @@ -99,7 +230,8 @@
private ExecutorComponent newExecutorComponent(
@NonNull final State state,
@NonNull final Map<String, String> properties,
@NonNull final TracerBinding tracerBinding) {
@NonNull final TracerBinding tracerBinding,
@NonNull final Set<Operation> customOps) {
final var bootstrapConfigProvider = new BootstrapConfigProviderImpl();
final var configProvider = new ConfigProviderImpl(false, null, properties);
final AtomicReference<ExecutorComponent> componentRef = new AtomicReference<>();
Expand All @@ -118,7 +250,8 @@
() -> state,
() -> componentRef.get().throttleServiceManager().activeThrottleDefinitionsOrThrow(),
ThrottleAccumulator::new));
final var contractService = new ContractServiceImpl(appContext, NOOP_VERIFICATION_STRATEGIES, tracerBinding);
final var contractService =
new ContractServiceImpl(appContext, NOOP_VERIFICATION_STRATEGIES, tracerBinding, customOps);
final var fileService = new FileServiceImpl();
final var scheduleService = new ScheduleServiceImpl();
final var component = DaggerExecutorComponent.builder()
Expand Down
Loading
Loading