Skip to content

Commit

Permalink
chore: (0.58) Support custom Operations in standalone executor (#17354
Browse files Browse the repository at this point in the history
)

Signed-off-by: Michael Tinker <michael.tinker@swirldslabs.com>
  • Loading branch information
tinker-michaelj authored Jan 14, 2025
1 parent 4e7c354 commit ad53b0c
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 32 deletions.
18 changes: 17 additions & 1 deletion hedera-node/hedera-app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2025 Hedera Hashgraph, LLC
*
* 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.
*/

plugins {
id("org.hiero.gradle.module.library")
id("org.hiero.gradle.feature.benchmark")
Expand Down Expand Up @@ -39,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 Down Expand Up @@ -46,12 +47,16 @@
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.ForkJoinPool;
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 @@ -70,21 +75,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 @@ -102,7 +233,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 @@ -128,7 +260,8 @@ private ExecutorComponent newExecutorComponent(
new TssLibraryImpl(appContext),
ForkJoinPool.commonPool(),
NO_OP_METRICS);
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 ad53b0c

Please # to comment.