Skip to content

Commit

Permalink
Support custom Set<Operation> in standalone executor
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Tinker <[email protected]>
  • Loading branch information
tinker-michaelj committed Jan 10, 2025
1 parent 02ba8df commit 0ea82d3
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 22 deletions.
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 @@ public interface TracerBinding extends Supplier<List<OperationTracer>> {
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) {
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());
}

/**
* 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 @@ public TransactionExecutor newExecutor(
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 @@ private ExecutorComponent newExecutorComponent(
() -> 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

0 comments on commit 0ea82d3

Please sign in to comment.