mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 20:47:59 -05:00
Merge branch 'main' into zkbesu
# Conflicts: # .github/workflows/draft-release.yml
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
### Breaking Changes
|
||||
- `--host-whitelist` has been deprecated since 2020 and this option is removed. Use the equivalent `--host-allowlist` instead.
|
||||
- Changed tracer API to include the mining beneficiary in BlockAwareOperationTracer::traceStartBlock [#8096](https://github.com/hyperledger/besu/pull/8096)
|
||||
- Change the input defaults on debug_trace* calls to not trace memory by default ("disableMemory": true, "disableStack": false, "disableStorage": false)
|
||||
- Change the output format of debug_trace* and trace_* calls to match Geth behaviour
|
||||
|
||||
### Upcoming Breaking Changes
|
||||
- `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge`
|
||||
@@ -20,7 +22,9 @@
|
||||
- Retrieve all transaction receipts for a block in one request [#6646](https://github.com/hyperledger/besu/pull/6646)
|
||||
- Implement EIP-7840: Add blob schedule to config files [#8042](https://github.com/hyperledger/besu/pull/8042)
|
||||
- Allow gasPrice (legacy) and 1559 gasPrice params to be specified simultaneously for `eth_call`, `eth_createAccessList`, and `eth_estimateGas` [#8059](https://github.com/hyperledger/besu/pull/8059)
|
||||
- Improve debug_traceBlock calls performance and reduce output size [#8076](https://github.com/hyperledger/besu/pull/8076)
|
||||
- Add support for EIP-7702 transaction in the txpool [#8018](https://github.com/hyperledger/besu/pull/8018) [#7984](https://github.com/hyperledger/besu/pull/7984)
|
||||
- Add support for `movePrecompileToAddress` in `StateOverrides` (`eth_call`)[8115](https://github.com/hyperledger/besu/pull/8115)
|
||||
|
||||
### Bug fixes
|
||||
- Fix serialization of state overrides when `movePrecompileToAddress` is present [#8204](https://github.com/hyperledger/besu/pull/8024)
|
||||
|
||||
@@ -140,8 +140,8 @@ public class CodeDelegationTransactionAcceptanceTest extends AcceptanceTestBase
|
||||
*/
|
||||
@Test
|
||||
public void shouldCheckNonceAfterNonceIncreaseOfSender() throws IOException {
|
||||
final long GAS_LIMIT = 1000000L;
|
||||
cluster.verify(authorizer.balanceEquals(Amount.ether(90000)));
|
||||
final long GAS_LIMIT = 1_000_000L;
|
||||
cluster.verify(authorizer.balanceEquals(Amount.ether(90_000)));
|
||||
|
||||
final CodeDelegation authorization =
|
||||
org.hyperledger.besu.ethereum.core.CodeDelegation.builder()
|
||||
@@ -159,7 +159,7 @@ public class CodeDelegationTransactionAcceptanceTest extends AcceptanceTestBase
|
||||
.type(TransactionType.DELEGATE_CODE)
|
||||
.chainId(BigInteger.valueOf(20211))
|
||||
.nonce(0)
|
||||
.maxPriorityFeePerGas(Wei.of(1000000000))
|
||||
.maxPriorityFeePerGas(Wei.of(1_000_000_000))
|
||||
.maxFeePerGas(Wei.fromHexString("0x02540BE400"))
|
||||
.gasLimit(GAS_LIMIT)
|
||||
.to(Address.fromHexStringStrict(authorizer.getAddress()))
|
||||
@@ -209,7 +209,7 @@ public class CodeDelegationTransactionAcceptanceTest extends AcceptanceTestBase
|
||||
.nonce(2)
|
||||
.maxPriorityFeePerGas(Wei.of(10))
|
||||
.maxFeePerGas(Wei.of(100))
|
||||
.gasLimit(21000)
|
||||
.gasLimit(21_000)
|
||||
.to(Address.fromHexStringStrict(otherAccount.getAddress()))
|
||||
.value(Wei.ONE)
|
||||
.payload(Bytes.EMPTY)
|
||||
|
||||
@@ -98,6 +98,10 @@ public class PragueAcceptanceTestHelper {
|
||||
executionPayload.toString(), parentBeaconBlockRoot, executionRequests.toString()));
|
||||
try (final Response newPayloadResponse = newPayloadRequest.execute()) {
|
||||
assertThat(newPayloadResponse.code()).isEqualTo(200);
|
||||
|
||||
final String responseStatus =
|
||||
mapper.readTree(newPayloadResponse.body().string()).get("result").get("status").asText();
|
||||
assertThat(responseStatus).isEqualTo("VALID");
|
||||
}
|
||||
|
||||
final Call moveChainAheadRequest = createEngineCall(createForkChoiceRequest(newBlockHash));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN" monitorInterval="30">
|
||||
<Configuration level="WARN" monitorInterval="30">
|
||||
<Properties>
|
||||
<Property name="root.log.level">INFO</Property>
|
||||
</Properties>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -74,6 +74,7 @@ import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
||||
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract;
|
||||
@@ -836,7 +837,8 @@ public class RunnerBuilder {
|
||||
besuPluginContext.getNamedPlugins(),
|
||||
dataDir,
|
||||
rpcEndpointServiceImpl,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
besuController.getProtocolManager().ethContext().getScheduler());
|
||||
|
||||
jsonRpcHttpService =
|
||||
Optional.of(
|
||||
@@ -882,7 +884,8 @@ public class RunnerBuilder {
|
||||
besuPluginContext.getNamedPlugins(),
|
||||
dataDir,
|
||||
rpcEndpointServiceImpl,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
besuController.getProtocolManager().ethContext().getScheduler());
|
||||
|
||||
final Optional<AuthenticationService> authToUse =
|
||||
engineJsonRpcConfiguration.get().isAuthenticationEnabled()
|
||||
@@ -978,7 +981,8 @@ public class RunnerBuilder {
|
||||
besuPluginContext.getNamedPlugins(),
|
||||
dataDir,
|
||||
rpcEndpointServiceImpl,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
besuController.getProtocolManager().ethContext().getScheduler());
|
||||
|
||||
createLogsSubscriptionService(
|
||||
context.getBlockchain(), subscriptionManager, privacyParameters, blockchainQueries);
|
||||
@@ -1059,7 +1063,8 @@ public class RunnerBuilder {
|
||||
besuPluginContext.getNamedPlugins(),
|
||||
dataDir,
|
||||
rpcEndpointServiceImpl,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
besuController.getProtocolManager().ethContext().getScheduler());
|
||||
|
||||
jsonRpcIpcService =
|
||||
Optional.of(
|
||||
@@ -1099,7 +1104,8 @@ public class RunnerBuilder {
|
||||
besuPluginContext.getNamedPlugins(),
|
||||
dataDir,
|
||||
rpcEndpointServiceImpl,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
besuController.getProtocolManager().ethContext().getScheduler());
|
||||
} else {
|
||||
inProcessRpcMethods = Map.of();
|
||||
}
|
||||
@@ -1262,7 +1268,8 @@ public class RunnerBuilder {
|
||||
final Map<String, BesuPlugin> namedPlugins,
|
||||
final Path dataDir,
|
||||
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
|
||||
final TransactionSimulator transactionSimulator) {
|
||||
final TransactionSimulator transactionSimulator,
|
||||
final EthScheduler ethScheduler) {
|
||||
// sync vertx for engine consensus API, to process requests in FIFO order;
|
||||
final Vertx consensusEngineServer = Vertx.vertx(new VertxOptions().setWorkerPoolSize(1));
|
||||
|
||||
@@ -1300,7 +1307,8 @@ public class RunnerBuilder {
|
||||
consensusEngineServer,
|
||||
apiConfiguration,
|
||||
enodeDnsConfiguration,
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
ethScheduler);
|
||||
methods.putAll(besuController.getAdditionalJsonRpcMethods(jsonRpcApis));
|
||||
|
||||
final var pluginMethods =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Configuration level="WARN">
|
||||
<Properties>
|
||||
<Property name="root.log.level">${env:LOG_LEVEL:-INFO}</Property>
|
||||
<Property name="root.log.logger">${env:LOGGER:-Console}</Property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Configuration level="WARN">
|
||||
<Properties>
|
||||
<Property name="root.log.level">DEBUG</Property>
|
||||
</Properties>
|
||||
|
||||
@@ -52,15 +52,9 @@ public class Hash extends DelegatingBytes32 {
|
||||
public static final Hash EMPTY = hash(Bytes.EMPTY);
|
||||
|
||||
/**
|
||||
* Hash of empty requests or "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"
|
||||
* Hash of empty requests or "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
*/
|
||||
public static final Hash EMPTY_REQUESTS_HASH =
|
||||
Hash.wrap(
|
||||
sha256(
|
||||
Bytes.concatenate(
|
||||
sha256(Bytes.of(RequestType.DEPOSIT.getSerializedType())),
|
||||
sha256(Bytes.of(RequestType.WITHDRAWAL.getSerializedType())),
|
||||
sha256(Bytes.of(RequestType.CONSOLIDATION.getSerializedType())))));
|
||||
public static final Hash EMPTY_REQUESTS_HASH = Hash.wrap(sha256(Bytes.EMPTY));
|
||||
|
||||
/**
|
||||
* Instantiates a new Hash.
|
||||
|
||||
@@ -36,16 +36,19 @@ public class StateOverride {
|
||||
private final Optional<Long> nonce;
|
||||
private final Optional<String> code;
|
||||
private final Optional<Map<String, String>> stateDiff;
|
||||
private final Optional<Address> movePrecompileToAddress;
|
||||
|
||||
private StateOverride(
|
||||
final Optional<Wei> balance,
|
||||
final Optional<Long> nonce,
|
||||
final Optional<String> code,
|
||||
final Optional<Map<String, String>> stateDiff) {
|
||||
final Optional<Map<String, String>> stateDiff,
|
||||
final Optional<Address> movePrecompileToAddress) {
|
||||
this.balance = balance;
|
||||
this.nonce = nonce;
|
||||
this.code = code;
|
||||
this.stateDiff = stateDiff;
|
||||
this.movePrecompileToAddress = movePrecompileToAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,6 +87,15 @@ public class StateOverride {
|
||||
return stateDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new address for the pre-compiled contract
|
||||
*
|
||||
* @return the new address for the pre-compiled contract if present
|
||||
*/
|
||||
public Optional<Address> getMovePrecompileToAddress() {
|
||||
return movePrecompileToAddress;
|
||||
}
|
||||
|
||||
/** Builder class for Account overrides */
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class Builder {
|
||||
@@ -91,6 +103,7 @@ public class StateOverride {
|
||||
private Optional<Long> nonce = Optional.empty();
|
||||
private Optional<String> code = Optional.empty();
|
||||
private Optional<Map<String, String>> stateDiff = Optional.empty();
|
||||
private Optional<Address> movePrecompileToAddress = Optional.empty();
|
||||
|
||||
/** Default constructor. */
|
||||
public Builder() {}
|
||||
@@ -139,13 +152,24 @@ public class StateOverride {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new address for the pre-compiled contract
|
||||
*
|
||||
* @param newPrecompileAddress the new address for the pre-compile contract
|
||||
* @return the builder
|
||||
*/
|
||||
public Builder withMovePrecompileToAddress(final Address newPrecompileAddress) {
|
||||
this.movePrecompileToAddress = Optional.ofNullable(newPrecompileAddress);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* build the account override from the builder
|
||||
*
|
||||
* @return account override
|
||||
*/
|
||||
public StateOverride build() {
|
||||
return new StateOverride(balance, nonce, code, stateDiff);
|
||||
return new StateOverride(balance, nonce, code, stateDiff, movePrecompileToAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +219,8 @@ public class StateOverride {
|
||||
+ code
|
||||
+ ", stateDiff="
|
||||
+ stateDiff
|
||||
+ ", movePrecompileToAddress="
|
||||
+ movePrecompileToAddress
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ public class HashTest {
|
||||
public void shouldGetExpectedValueForEmptyRequestsHash() {
|
||||
assertThat(Hash.EMPTY_REQUESTS_HASH)
|
||||
.isEqualTo(
|
||||
Hash.fromHexString(
|
||||
"0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"));
|
||||
Hash.fromHexString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -51,6 +51,7 @@ import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Path;
|
||||
@@ -228,6 +229,7 @@ public class JsonRpcTestMethodsFactory {
|
||||
Vertx.vertx(new VertxOptions().setWorkerPoolSize(1)),
|
||||
ImmutableApiConfiguration.builder().build(),
|
||||
Optional.empty(),
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
new DeterministicEthScheduler());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright contributors to 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.api.jsonrpc.internal.methods;
|
||||
|
||||
import static org.hyperledger.besu.services.pipeline.PipelineBuilder.createPipelineFrom;
|
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceOptions;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
import org.hyperledger.besu.services.pipeline.Pipeline;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
public abstract class AbstractDebugTraceBlock implements JsonRpcMethod {
|
||||
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final LabelledMetric<Counter> outputCounter;
|
||||
private final Supplier<BlockchainQueries> blockchainQueriesSupplier;
|
||||
private final EthScheduler ethScheduler;
|
||||
|
||||
public AbstractDebugTraceBlock(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ObservableMetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
this.blockchainQueriesSupplier = Suppliers.ofInstance(blockchainQueries);
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.outputCounter =
|
||||
metricsSystem.createLabelledCounter(
|
||||
BesuMetricCategory.BLOCKCHAIN,
|
||||
"transactions_debugTraceblock_pipeline_processed_total",
|
||||
"Number of transactions processed for each block",
|
||||
"step",
|
||||
"action");
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
protected BlockchainQueries getBlockchainQueries() {
|
||||
return blockchainQueriesSupplier.get();
|
||||
}
|
||||
|
||||
protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContext) {
|
||||
final TraceOptions traceOptions;
|
||||
try {
|
||||
traceOptions =
|
||||
requestContext
|
||||
.getOptionalParameter(1, TransactionTraceParams.class)
|
||||
.map(TransactionTraceParams::traceOptions)
|
||||
.orElse(TraceOptions.DEFAULT);
|
||||
} catch (JsonRpcParameter.JsonRpcParameterException e) {
|
||||
throw new InvalidJsonRpcParameters(
|
||||
"Invalid transaction trace parameter (index 1)",
|
||||
RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS,
|
||||
e);
|
||||
}
|
||||
return traceOptions;
|
||||
}
|
||||
|
||||
protected Collection<DebugTraceTransactionResult> getTraces(
|
||||
final JsonRpcRequestContext requestContext,
|
||||
final TraceOptions traceOptions,
|
||||
final Optional<Block> maybeBlock) {
|
||||
return maybeBlock
|
||||
.flatMap(
|
||||
block ->
|
||||
Tracer.processTracing(
|
||||
getBlockchainQueries(),
|
||||
block.getHash(),
|
||||
traceableState -> {
|
||||
List<DebugTraceTransactionResult> tracesList =
|
||||
Collections.synchronizedList(new ArrayList<>());
|
||||
final ProtocolSpec protocolSpec =
|
||||
protocolSchedule.getByBlockHeader(block.getHeader());
|
||||
final MainnetTransactionProcessor transactionProcessor =
|
||||
protocolSpec.getTransactionProcessor();
|
||||
final TraceBlock.ChainUpdater chainUpdater =
|
||||
new TraceBlock.ChainUpdater(traceableState);
|
||||
|
||||
TransactionSource transactionSource = new TransactionSource(block);
|
||||
DebugOperationTracer debugOperationTracer =
|
||||
new DebugOperationTracer(traceOptions, true);
|
||||
ExecuteTransactionStep executeTransactionStep =
|
||||
new ExecuteTransactionStep(
|
||||
chainUpdater,
|
||||
transactionProcessor,
|
||||
getBlockchainQueries().getBlockchain(),
|
||||
debugOperationTracer,
|
||||
protocolSpec,
|
||||
block);
|
||||
DebugTraceTransactionStep debugTraceTransactionStep =
|
||||
new DebugTraceTransactionStep();
|
||||
Pipeline<TransactionTrace> traceBlockPipeline =
|
||||
createPipelineFrom(
|
||||
"getTransactions",
|
||||
transactionSource,
|
||||
4,
|
||||
outputCounter,
|
||||
false,
|
||||
"debug_trace_block")
|
||||
.thenProcess("executeTransaction", executeTransactionStep)
|
||||
.thenProcessAsyncOrdered(
|
||||
"debugTraceTransactionStep", debugTraceTransactionStep, 4)
|
||||
.andFinishWith("collect_results", tracesList::add);
|
||||
|
||||
try {
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Optional.of(tracesList);
|
||||
}))
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -18,10 +18,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
@@ -31,32 +27,32 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceOptions;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLP;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPException;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DebugTraceBlock implements JsonRpcMethod {
|
||||
public class DebugTraceBlock extends AbstractDebugTraceBlock {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DebugTraceBlock.class);
|
||||
private final Supplier<BlockTracer> blockTracerSupplier;
|
||||
private final BlockHeaderFunctions blockHeaderFunctions;
|
||||
private final BlockchainQueries blockchainQueries;
|
||||
|
||||
public DebugTraceBlock(
|
||||
final Supplier<BlockTracer> blockTracerSupplier,
|
||||
final BlockHeaderFunctions blockHeaderFunctions,
|
||||
final BlockchainQueries blockchainQueries) {
|
||||
this.blockTracerSupplier = blockTracerSupplier;
|
||||
this.blockHeaderFunctions = blockHeaderFunctions;
|
||||
this.blockchainQueries = blockchainQueries;
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ObservableMetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler);
|
||||
this.blockHeaderFunctions = ScheduleBasedBlockHeaderFunctions.create(protocolSchedule);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,7 +66,7 @@ public class DebugTraceBlock implements JsonRpcMethod {
|
||||
try {
|
||||
final String input = requestContext.getRequiredParameter(0, String.class);
|
||||
block = Block.readFrom(RLP.input(Bytes.fromHexString(input)), this.blockHeaderFunctions);
|
||||
} catch (final RLPException e) {
|
||||
} catch (final RLPException | IllegalArgumentException e) {
|
||||
LOG.debug("Failed to parse block RLP (index 0)", e);
|
||||
return new JsonRpcErrorResponse(
|
||||
requestContext.getRequest().getId(), RpcErrorType.INVALID_BLOCK_PARAMS);
|
||||
@@ -78,35 +74,14 @@ public class DebugTraceBlock implements JsonRpcMethod {
|
||||
throw new InvalidJsonRpcParameters(
|
||||
"Invalid block params (index 0)", RpcErrorType.INVALID_BLOCK_PARAMS, e);
|
||||
}
|
||||
final TraceOptions traceOptions;
|
||||
try {
|
||||
traceOptions =
|
||||
requestContext
|
||||
.getOptionalParameter(1, TransactionTraceParams.class)
|
||||
.map(TransactionTraceParams::traceOptions)
|
||||
.orElse(TraceOptions.DEFAULT);
|
||||
} catch (JsonRpcParameterException e) {
|
||||
throw new InvalidJsonRpcParameters(
|
||||
"Invalid transaction trace parameter (index 1)",
|
||||
RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS,
|
||||
e);
|
||||
}
|
||||
final TraceOptions traceOptions = getTraceOptions(requestContext);
|
||||
|
||||
if (this.blockchainQueries.blockByHash(block.getHeader().getParentHash()).isPresent()) {
|
||||
if (getBlockchainQueries()
|
||||
.getBlockchain()
|
||||
.getBlockByHash(block.getHeader().getParentHash())
|
||||
.isPresent()) {
|
||||
final Collection<DebugTraceTransactionResult> results =
|
||||
Tracer.processTracing(
|
||||
blockchainQueries,
|
||||
Optional.of(block.getHeader()),
|
||||
mutableWorldState ->
|
||||
blockTracerSupplier
|
||||
.get()
|
||||
.trace(
|
||||
mutableWorldState,
|
||||
block,
|
||||
new DebugOperationTracer(traceOptions, true))
|
||||
.map(BlockTrace::getTransactionTraces)
|
||||
.map(DebugTraceTransactionResult::of))
|
||||
.orElse(null);
|
||||
getTraces(requestContext, traceOptions, Optional.ofNullable(block));
|
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), results);
|
||||
} else {
|
||||
return new JsonRpcErrorResponse(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -19,31 +19,28 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceOptions;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.Optional;
|
||||
|
||||
public class DebugTraceBlockByHash implements JsonRpcMethod {
|
||||
|
||||
private final Supplier<BlockTracer> blockTracerSupplier;
|
||||
private final Supplier<BlockchainQueries> blockchainQueries;
|
||||
public class DebugTraceBlockByHash extends AbstractDebugTraceBlock {
|
||||
|
||||
public DebugTraceBlockByHash(
|
||||
final Supplier<BlockTracer> blockTracerSupplier,
|
||||
final Supplier<BlockchainQueries> blockchainQueriesSupplier) {
|
||||
this.blockTracerSupplier = blockTracerSupplier;
|
||||
this.blockchainQueries = blockchainQueriesSupplier;
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ObservableMetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,34 +57,12 @@ public class DebugTraceBlockByHash implements JsonRpcMethod {
|
||||
throw new InvalidJsonRpcParameters(
|
||||
"Invalid block hash parameter (index 0)", RpcErrorType.INVALID_BLOCK_HASH_PARAMS, e);
|
||||
}
|
||||
final TraceOptions traceOptions;
|
||||
try {
|
||||
traceOptions =
|
||||
requestContext
|
||||
.getOptionalParameter(1, TransactionTraceParams.class)
|
||||
.map(TransactionTraceParams::traceOptions)
|
||||
.orElse(TraceOptions.DEFAULT);
|
||||
} catch (JsonRpcParameterException e) {
|
||||
throw new InvalidJsonRpcParameters(
|
||||
"Invalid transaction trace parameter (index 1)",
|
||||
RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS,
|
||||
e);
|
||||
}
|
||||
|
||||
TraceOptions traceOptions = getTraceOptions(requestContext);
|
||||
Optional<Block> maybeBlock = getBlockchainQueries().getBlockchain().getBlockByHash(blockHash);
|
||||
|
||||
final Collection<DebugTraceTransactionResult> results =
|
||||
Tracer.processTracing(
|
||||
blockchainQueries.get(),
|
||||
blockHash,
|
||||
mutableWorldState ->
|
||||
blockTracerSupplier
|
||||
.get()
|
||||
.trace(
|
||||
mutableWorldState,
|
||||
blockHash,
|
||||
new DebugOperationTracer(traceOptions, true))
|
||||
.map(BlockTrace::getTransactionTraces)
|
||||
.map(DebugTraceTransactionResult::of))
|
||||
.orElse(null);
|
||||
getTraces(requestContext, traceOptions, maybeBlock);
|
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), results);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -14,33 +14,59 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import static org.hyperledger.besu.services.pipeline.PipelineBuilder.createPipelineFrom;
|
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.JsonRpcParameter.JsonRpcParameterException;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.TransactionTraceParams;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceOptions;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
import org.hyperledger.besu.services.pipeline.Pipeline;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod {
|
||||
|
||||
private final Supplier<BlockTracer> blockTracerSupplier;
|
||||
protected final ProtocolSchedule protocolSchedule;
|
||||
private final LabelledMetric<Counter> outputCounter;
|
||||
private final EthScheduler ethScheduler;
|
||||
|
||||
public DebugTraceBlockByNumber(
|
||||
final Supplier<BlockTracer> blockTracerSupplier, final BlockchainQueries blockchain) {
|
||||
super(blockchain);
|
||||
this.blockTracerSupplier = blockTracerSupplier;
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ObservableMetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(blockchainQueries);
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.outputCounter =
|
||||
metricsSystem.createLabelledCounter(
|
||||
BesuMetricCategory.BLOCKCHAIN,
|
||||
"transactions_debugtraceblock_pipeline_processed_total",
|
||||
"Number of transactions processed for each block",
|
||||
"step",
|
||||
"action");
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +87,7 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod {
|
||||
@Override
|
||||
protected Object resultByBlockNumber(
|
||||
final JsonRpcRequestContext request, final long blockNumber) {
|
||||
final Optional<Hash> blockHash = getBlockchainQueries().getBlockHashByNumber(blockNumber);
|
||||
|
||||
final TraceOptions traceOptions;
|
||||
try {
|
||||
traceOptions =
|
||||
@@ -75,22 +101,58 @@ public class DebugTraceBlockByNumber extends AbstractBlockParameterMethod {
|
||||
RpcErrorType.INVALID_TRANSACTION_TRACE_PARAMS,
|
||||
e);
|
||||
}
|
||||
Optional<Block> maybeBlock =
|
||||
getBlockchainQueries().getBlockchain().getBlockByNumber(blockNumber);
|
||||
|
||||
return blockHash
|
||||
return maybeBlock
|
||||
.flatMap(
|
||||
hash ->
|
||||
block ->
|
||||
Tracer.processTracing(
|
||||
blockchainQueriesSupplier.get(),
|
||||
hash,
|
||||
mutableWorldState ->
|
||||
blockTracerSupplier
|
||||
.get()
|
||||
.trace(
|
||||
mutableWorldState,
|
||||
hash,
|
||||
new DebugOperationTracer(traceOptions, true))
|
||||
.map(BlockTrace::getTransactionTraces)
|
||||
.map(DebugTraceTransactionResult::of)))
|
||||
getBlockchainQueries(),
|
||||
Optional.of(block.getHeader()),
|
||||
traceableState -> {
|
||||
List<DebugTraceTransactionResult> tracesList =
|
||||
Collections.synchronizedList(new ArrayList<>());
|
||||
final ProtocolSpec protocolSpec =
|
||||
protocolSchedule.getByBlockHeader(block.getHeader());
|
||||
final MainnetTransactionProcessor transactionProcessor =
|
||||
protocolSpec.getTransactionProcessor();
|
||||
final TraceBlock.ChainUpdater chainUpdater =
|
||||
new TraceBlock.ChainUpdater(traceableState);
|
||||
|
||||
TransactionSource transactionSource = new TransactionSource(block);
|
||||
DebugOperationTracer debugOperationTracer =
|
||||
new DebugOperationTracer(traceOptions, true);
|
||||
ExecuteTransactionStep executeTransactionStep =
|
||||
new ExecuteTransactionStep(
|
||||
chainUpdater,
|
||||
transactionProcessor,
|
||||
getBlockchainQueries().getBlockchain(),
|
||||
debugOperationTracer,
|
||||
protocolSpec,
|
||||
block);
|
||||
DebugTraceTransactionStep debugTraceTransactionStep =
|
||||
new DebugTraceTransactionStep();
|
||||
Pipeline<TransactionTrace> traceBlockPipeline =
|
||||
createPipelineFrom(
|
||||
"getTransactions",
|
||||
transactionSource,
|
||||
4,
|
||||
outputCounter,
|
||||
false,
|
||||
"debug_trace_block_by_number")
|
||||
.thenProcess("executeTransaction", executeTransactionStep)
|
||||
.thenProcessAsyncOrdered(
|
||||
"debugTraceTransactionStep", debugTraceTransactionStep, 4)
|
||||
.andFinishWith("collect_results", tracesList::add);
|
||||
|
||||
try {
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Optional.of(tracesList);
|
||||
}))
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.api.jsonrpc.internal.methods;
|
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class DebugTraceTransactionStep
|
||||
implements Function<TransactionTrace, CompletableFuture<DebugTraceTransactionResult>> {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<DebugTraceTransactionResult> apply(
|
||||
final TransactionTrace transactionTrace) {
|
||||
return CompletableFuture.completedFuture(new DebugTraceTransactionResult(transactionTrace));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -39,7 +39,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
@@ -57,11 +56,13 @@ public class TraceBlock extends AbstractBlockParameterMethod {
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
protected final ProtocolSchedule protocolSchedule;
|
||||
private final LabelledMetric<Counter> outputCounter;
|
||||
protected final EthScheduler ethScheduler;
|
||||
|
||||
public TraceBlock(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries queries,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(queries);
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.outputCounter =
|
||||
@@ -71,6 +72,7 @@ public class TraceBlock extends AbstractBlockParameterMethod {
|
||||
"Number of transactions processed for each block",
|
||||
"step",
|
||||
"action");
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,16 +155,7 @@ public class TraceBlock extends AbstractBlockParameterMethod {
|
||||
traceStream -> traceStream.forEachOrdered(buildArrayNodeStep));
|
||||
|
||||
try {
|
||||
if (getBlockchainQueries().getEthScheduler().isPresent()) {
|
||||
getBlockchainQueries()
|
||||
.getEthScheduler()
|
||||
.get()
|
||||
.startPipeline(traceBlockPipeline)
|
||||
.get();
|
||||
} else {
|
||||
EthScheduler ethScheduler = new EthScheduler(1, 1, 1, 1, new NoOpMetricsSystem());
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
}
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -43,7 +43,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
@@ -74,8 +73,9 @@ public class TraceFilter extends TraceBlock {
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final Long maxRange,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(protocolSchedule, blockchainQueries, metricsSystem);
|
||||
final MetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler);
|
||||
this.maxRange = maxRange;
|
||||
this.outputCounter =
|
||||
metricsSystem.createLabelledCounter(
|
||||
@@ -196,14 +196,7 @@ public class TraceFilter extends TraceBlock {
|
||||
traceStream -> traceStream.forEachOrdered(buildArrayNodeStep));
|
||||
|
||||
try {
|
||||
Optional<EthScheduler> ethSchedulerOpt =
|
||||
getBlockchainQueries().getEthScheduler();
|
||||
|
||||
ethSchedulerOpt
|
||||
.orElse(new EthScheduler(1, 1, 1, 1, new NoOpMetricsSystem()))
|
||||
.startPipeline(traceBlockPipeline)
|
||||
.get();
|
||||
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -38,7 +38,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
@@ -60,11 +59,13 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod {
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final LabelledMetric<Counter> outputCounter;
|
||||
private final EthScheduler ethScheduler;
|
||||
|
||||
public TraceReplayBlockTransactions(
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final BlockchainQueries queries,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
super(queries);
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.outputCounter =
|
||||
@@ -74,6 +75,7 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod {
|
||||
"Number of transactions processed for each block",
|
||||
"step",
|
||||
"action");
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,16 +175,7 @@ public class TraceReplayBlockTransactions extends AbstractBlockParameterMethod {
|
||||
"traceReplayTransaction", traceReplayTransactionStep, 4)
|
||||
.andFinishWith("buildArrayNode", buildArrayNodeStep::accept);
|
||||
try {
|
||||
if (getBlockchainQueries().getEthScheduler().isPresent()) {
|
||||
getBlockchainQueries()
|
||||
.getEthScheduler()
|
||||
.get()
|
||||
.startPipeline(traceBlockPipeline)
|
||||
.get();
|
||||
} else {
|
||||
EthScheduler ethScheduler = new EthScheduler(1, 1, 1, 1, new NoOpMetricsSystem());
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
}
|
||||
ethScheduler.startPipeline(traceBlockPipeline).get();
|
||||
} catch (final InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
@@ -22,6 +22,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.Executi
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.RequestValidatorProvider.getRequestsValidator;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
|
||||
import static org.hyperledger.besu.metrics.BesuMetricCategory.BLOCK_PROCESSING;
|
||||
|
||||
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
@@ -61,6 +62,7 @@ import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator;
|
||||
import org.hyperledger.besu.ethereum.rlp.RLPException;
|
||||
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.exception.StorageException;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
@@ -69,7 +71,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.json.Json;
|
||||
@@ -85,6 +86,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
private static final BlockHeaderFunctions headerFunctions = new MainnetBlockHeaderFunctions();
|
||||
private final MergeMiningCoordinator mergeCoordinator;
|
||||
private final EthPeers ethPeers;
|
||||
private long lastExecutionTime = 0L;
|
||||
|
||||
public AbstractEngineNewPayload(
|
||||
final Vertx vertx,
|
||||
@@ -92,10 +94,16 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
final ProtocolContext protocolContext,
|
||||
final MergeMiningCoordinator mergeCoordinator,
|
||||
final EthPeers ethPeers,
|
||||
final EngineCallListener engineCallListener) {
|
||||
final EngineCallListener engineCallListener,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(vertx, protocolSchedule, protocolContext, engineCallListener);
|
||||
this.mergeCoordinator = mergeCoordinator;
|
||||
this.ethPeers = ethPeers;
|
||||
metricsSystem.createLongGauge(
|
||||
BLOCK_PROCESSING,
|
||||
"execution_time_head",
|
||||
"The execution time of the last block (head)",
|
||||
this::getLastExecutionTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -347,8 +355,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
// execute block and return result response
|
||||
final long startTimeMs = System.currentTimeMillis();
|
||||
final BlockProcessingResult executionResult = mergeCoordinator.rememberBlock(block);
|
||||
|
||||
if (executionResult.isSuccessful()) {
|
||||
lastExecutionTime = System.currentTimeMillis() - startTimeMs;
|
||||
logImportedBlockInfo(
|
||||
block,
|
||||
blobTransactions.stream()
|
||||
@@ -356,7 +364,7 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
.flatMap(Optional::stream)
|
||||
.mapToInt(List::size)
|
||||
.sum(),
|
||||
(System.currentTimeMillis() - startTimeMs) / 1000.0,
|
||||
lastExecutionTime / 1000.0,
|
||||
executionResult.getNbParallelizedTransations());
|
||||
return respondWith(reqId, blockParam, newBlockHeader.getHash(), VALID);
|
||||
} else {
|
||||
@@ -587,8 +595,12 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
|
||||
return maybeRequestsParam.map(
|
||||
requests ->
|
||||
IntStream.range(0, requests.size())
|
||||
.mapToObj(i -> new Request(RequestType.of(i), Bytes.fromHexString(requests.get(i))))
|
||||
requests.stream()
|
||||
.map(
|
||||
s -> {
|
||||
final Bytes request = Bytes.fromHexString(s);
|
||||
return new Request(RequestType.of(request.get(0)), request.slice(1));
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@@ -629,4 +641,8 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
|
||||
messageArgs.add(ethPeers.peerCount());
|
||||
LOG.info(String.format(message.toString(), messageArgs.toArray()));
|
||||
}
|
||||
|
||||
private long getLastExecutionTime() {
|
||||
return this.lastExecutionTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
@@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -41,8 +42,16 @@ public class EngineNewPayloadV1 extends AbstractEngineNewPayload {
|
||||
final ProtocolContext protocolContext,
|
||||
final MergeMiningCoordinator mergeCoordinator,
|
||||
final EthPeers ethPeers,
|
||||
final EngineCallListener engineCallListener) {
|
||||
super(vertx, protocolSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
|
||||
final EngineCallListener engineCallListener,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(
|
||||
vertx,
|
||||
protocolSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener,
|
||||
metricsSystem);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
@@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -43,8 +44,16 @@ public class EngineNewPayloadV2 extends AbstractEngineNewPayload {
|
||||
final ProtocolContext protocolContext,
|
||||
final MergeMiningCoordinator mergeCoordinator,
|
||||
final EthPeers ethPeers,
|
||||
final EngineCallListener engineCallListener) {
|
||||
super(vertx, protocolSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
|
||||
final EngineCallListener engineCallListener,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(
|
||||
vertx,
|
||||
protocolSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener,
|
||||
metricsSystem);
|
||||
cancunMilestone = protocolSchedule.milestoneFor(CANCUN);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -40,9 +41,16 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload {
|
||||
final ProtocolContext protocolContext,
|
||||
final MergeMiningCoordinator mergeCoordinator,
|
||||
final EthPeers ethPeers,
|
||||
final EngineCallListener engineCallListener) {
|
||||
final EngineCallListener engineCallListener,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(
|
||||
vertx, timestampSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
|
||||
vertx,
|
||||
timestampSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener,
|
||||
metricsSystem);
|
||||
this.cancunMilestone = timestampSchedule.milestoneFor(CANCUN);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -40,9 +41,16 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload {
|
||||
final ProtocolContext protocolContext,
|
||||
final MergeMiningCoordinator mergeCoordinator,
|
||||
final EthPeers ethPeers,
|
||||
final EngineCallListener engineCallListener) {
|
||||
final EngineCallListener engineCallListener,
|
||||
final MetricsSystem metricsSystem) {
|
||||
super(
|
||||
vertx, timestampSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
|
||||
vertx,
|
||||
timestampSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener,
|
||||
metricsSystem);
|
||||
pragueMilestone = timestampSchedule.milestoneFor(PRAGUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,9 @@ public class BlockResultFactory {
|
||||
rqs ->
|
||||
rqs.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.filter(r -> !r.getData().isEmpty())
|
||||
.map(Request::getEncodedRequest)
|
||||
.map(Bytes::toHexString)
|
||||
.toList());
|
||||
|
||||
final BlobsBundleV1 blobsBundleV1 =
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceFrame;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -35,10 +36,10 @@ public class DebugTraceTransactionResult {
|
||||
public DebugTraceTransactionResult(final TransactionTrace transactionTrace) {
|
||||
gas = transactionTrace.getGas();
|
||||
returnValue = transactionTrace.getResult().getOutput().toString().substring(2);
|
||||
structLogs =
|
||||
transactionTrace.getTraceFrames().stream()
|
||||
.map(DebugTraceTransactionResult::createStructLog)
|
||||
.collect(Collectors.toList());
|
||||
structLogs = new ArrayList<>(transactionTrace.getTraceFrames().size());
|
||||
transactionTrace.getTraceFrames().parallelStream()
|
||||
.map(DebugTraceTransactionResult::createStructLog)
|
||||
.forEachOrdered(structLogs::add);
|
||||
failed = !transactionTrace.getResult().isSuccessful();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,15 @@ import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
@JsonPropertyOrder({"pc", "op", "gas", "gasCost", "depth", "stack", "memory", "storage"})
|
||||
public class StructLog {
|
||||
|
||||
private static final char[] hexChars = "0123456789abcdef".toCharArray();
|
||||
private final int depth;
|
||||
private final long gas;
|
||||
private final long gasCost;
|
||||
@@ -39,7 +40,6 @@ public class StructLog {
|
||||
private final String[] stack;
|
||||
private final Object storage;
|
||||
private final String reason;
|
||||
static final String bytes32ZeroString = Bytes32.ZERO.toUnprefixedHexString();
|
||||
|
||||
public StructLog(final TraceFrame traceFrame) {
|
||||
depth = traceFrame.getDepth() + 1;
|
||||
@@ -48,7 +48,9 @@ public class StructLog {
|
||||
memory =
|
||||
traceFrame
|
||||
.getMemory()
|
||||
.map(a -> Arrays.stream(a).map(Bytes::toUnprefixedHexString).toArray(String[]::new))
|
||||
.map(
|
||||
a ->
|
||||
Arrays.stream(a).map(bytes -> toCompactHex(bytes, true)).toArray(String[]::new))
|
||||
.orElse(null);
|
||||
op = traceFrame.getOpcode();
|
||||
pc = traceFrame.getPc();
|
||||
@@ -57,28 +59,17 @@ public class StructLog {
|
||||
.getStack()
|
||||
.map(
|
||||
a ->
|
||||
Arrays.stream(a)
|
||||
.map(Bytes::toUnprefixedHexString)
|
||||
.map(this::stringLeftPadTo64)
|
||||
.toArray(String[]::new))
|
||||
Arrays.stream(a).map(bytes -> toCompactHex(bytes, true)).toArray(String[]::new))
|
||||
.orElse(null);
|
||||
|
||||
storage = traceFrame.getStorage().map(StructLog::formatStorage).orElse(null);
|
||||
reason = traceFrame.getRevertReason().map(Bytes::toShortHexString).orElse(null);
|
||||
}
|
||||
|
||||
private String stringLeftPadTo64(final String unPaddedHexString) {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
sb.append(bytes32ZeroString, 0, 64 - unPaddedHexString.length());
|
||||
sb.append(unPaddedHexString);
|
||||
return sb.toString();
|
||||
reason = traceFrame.getRevertReason().map(bytes -> toCompactHex(bytes, true)).orElse(null);
|
||||
}
|
||||
|
||||
private static Map<String, String> formatStorage(final Map<UInt256, UInt256> storage) {
|
||||
final Map<String, String> formattedStorage = new TreeMap<>();
|
||||
storage.forEach(
|
||||
(key, value) ->
|
||||
formattedStorage.put(key.toUnprefixedHexString(), value.toUnprefixedHexString()));
|
||||
(key, value) -> formattedStorage.put(toCompactHex(key, false), toCompactHex(value, false)));
|
||||
return formattedStorage;
|
||||
}
|
||||
|
||||
@@ -98,6 +89,7 @@ public class StructLog {
|
||||
}
|
||||
|
||||
@JsonGetter("memory")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public String[] memory() {
|
||||
return memory;
|
||||
}
|
||||
@@ -113,16 +105,19 @@ public class StructLog {
|
||||
}
|
||||
|
||||
@JsonGetter("stack")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public String[] stack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
@JsonGetter("storage")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public Object storage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
@JsonGetter("reason")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public String reason() {
|
||||
return reason;
|
||||
}
|
||||
@@ -153,4 +148,39 @@ public class StructLog {
|
||||
result = 31 * result + Arrays.hashCode(stack);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String toCompactHex(final Bytes abytes, final boolean prefix) {
|
||||
if (abytes.isEmpty()) {
|
||||
if (prefix) return "0x0";
|
||||
else return "0";
|
||||
}
|
||||
|
||||
byte[] bytes = abytes.toArrayUnsafe();
|
||||
final int size = bytes.length;
|
||||
final StringBuilder result = new StringBuilder(prefix ? (size * 2) + 2 : size * 2);
|
||||
|
||||
if (prefix) {
|
||||
result.append("0x");
|
||||
}
|
||||
|
||||
boolean leadingZero = true;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
byte b = bytes[i];
|
||||
|
||||
int highNibble = (b >> 4) & 0xF;
|
||||
if (!leadingZero || highNibble != 0) {
|
||||
result.append(hexChars[highNibble]);
|
||||
leadingZero = false;
|
||||
}
|
||||
|
||||
int lowNibble = b & 0xF;
|
||||
if (!leadingZero || lowNibble != 0 || i == size - 1) {
|
||||
result.append(hexChars[lowNibble]);
|
||||
leadingZero = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -43,9 +43,9 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionT
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
|
||||
@@ -64,6 +64,7 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final Synchronizer synchronizer;
|
||||
private final Path dataDir;
|
||||
private final TransactionSimulator transactionSimulator;
|
||||
private final EthScheduler ethScheduler;
|
||||
|
||||
DebugJsonRpcMethods(
|
||||
final BlockchainQueries blockchainQueries,
|
||||
@@ -73,7 +74,8 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final TransactionPool transactionPool,
|
||||
final Synchronizer synchronizer,
|
||||
final Path dataDir,
|
||||
final TransactionSimulator transactionSimulator) {
|
||||
final TransactionSimulator transactionSimulator,
|
||||
final EthScheduler ethScheduler) {
|
||||
this.blockchainQueries = blockchainQueries;
|
||||
this.protocolContext = protocolContext;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
@@ -82,6 +84,7 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
this.synchronizer = synchronizer;
|
||||
this.dataDir = dataDir;
|
||||
this.transactionSimulator = transactionSimulator;
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,14 +103,12 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
new DebugStorageRangeAt(blockchainQueries, blockReplay),
|
||||
new DebugMetrics(metricsSystem),
|
||||
new DebugResyncWorldstate(protocolContext, synchronizer),
|
||||
new DebugTraceBlock(
|
||||
() -> new BlockTracer(blockReplay),
|
||||
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule),
|
||||
blockchainQueries),
|
||||
new DebugTraceBlock(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler),
|
||||
new DebugSetHead(blockchainQueries, protocolContext),
|
||||
new DebugReplayBlock(blockchainQueries, protocolContext, protocolSchedule),
|
||||
new DebugTraceBlockByNumber(() -> new BlockTracer(blockReplay), blockchainQueries),
|
||||
new DebugTraceBlockByHash(() -> new BlockTracer(blockReplay), () -> blockchainQueries),
|
||||
new DebugTraceBlockByNumber(
|
||||
protocolSchedule, blockchainQueries, metricsSystem, ethScheduler),
|
||||
new DebugTraceBlockByHash(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler),
|
||||
new DebugBatchSendRawTransaction(transactionPool),
|
||||
new DebugGetBadBlocks(protocolContext, blockResult),
|
||||
new DebugStandardTraceBlockToFile(
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -63,6 +64,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final String clientVersion;
|
||||
private final String commit;
|
||||
private final TransactionPool transactionPool;
|
||||
private final MetricsSystem metricsSystem;
|
||||
|
||||
ExecutionEngineJsonRpcMethods(
|
||||
final MiningCoordinator miningCoordinator,
|
||||
@@ -72,7 +74,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final Vertx consensusEngineServer,
|
||||
final String clientVersion,
|
||||
final String commit,
|
||||
final TransactionPool transactionPool) {
|
||||
final TransactionPool transactionPool,
|
||||
final MetricsSystem metricsSystem) {
|
||||
this.mergeCoordinator =
|
||||
Optional.ofNullable(miningCoordinator)
|
||||
.filter(mc -> mc.isCompatibleWithEngineApi())
|
||||
@@ -84,6 +87,7 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
this.clientVersion = clientVersion;
|
||||
this.commit = commit;
|
||||
this.transactionPool = transactionPool;
|
||||
this.metricsSystem = metricsSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,21 +121,24 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
protocolContext,
|
||||
mergeCoordinator.get(),
|
||||
ethPeers,
|
||||
engineQosTimer),
|
||||
engineQosTimer,
|
||||
metricsSystem),
|
||||
new EngineNewPayloadV2(
|
||||
consensusEngineServer,
|
||||
protocolSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator.get(),
|
||||
ethPeers,
|
||||
engineQosTimer),
|
||||
engineQosTimer,
|
||||
metricsSystem),
|
||||
new EngineNewPayloadV3(
|
||||
consensusEngineServer,
|
||||
protocolSchedule,
|
||||
protocolContext,
|
||||
mergeCoordinator.get(),
|
||||
ethPeers,
|
||||
engineQosTimer),
|
||||
engineQosTimer,
|
||||
metricsSystem),
|
||||
new EngineForkchoiceUpdatedV1(
|
||||
consensusEngineServer,
|
||||
protocolSchedule,
|
||||
@@ -193,7 +200,8 @@ public class ExecutionEngineJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
protocolContext,
|
||||
mergeCoordinator.get(),
|
||||
ethPeers,
|
||||
engineQosTimer));
|
||||
engineQosTimer,
|
||||
metricsSystem));
|
||||
}
|
||||
|
||||
return mapOf(executionEngineApisSupported);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
||||
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.p2p.network.P2PNetwork;
|
||||
@@ -87,7 +88,8 @@ public class JsonRpcMethodsFactory {
|
||||
final Vertx consensusEngineServer,
|
||||
final ApiConfiguration apiConfiguration,
|
||||
final Optional<EnodeDnsConfiguration> enodeDnsConfiguration,
|
||||
final TransactionSimulator transactionSimulator) {
|
||||
final TransactionSimulator transactionSimulator,
|
||||
final EthScheduler ethScheduler) {
|
||||
final Map<String, JsonRpcMethod> enabled = new HashMap<>();
|
||||
if (!rpcApis.isEmpty()) {
|
||||
final JsonRpcMethod modules = new RpcModules(rpcApis);
|
||||
@@ -113,7 +115,8 @@ public class JsonRpcMethodsFactory {
|
||||
transactionPool,
|
||||
synchronizer,
|
||||
dataDir,
|
||||
transactionSimulator),
|
||||
transactionSimulator,
|
||||
ethScheduler),
|
||||
new EeaJsonRpcMethods(
|
||||
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
|
||||
new ExecutionEngineJsonRpcMethods(
|
||||
@@ -124,7 +127,8 @@ public class JsonRpcMethodsFactory {
|
||||
consensusEngineServer,
|
||||
clientVersion,
|
||||
commit,
|
||||
transactionPool),
|
||||
transactionPool,
|
||||
metricsSystem),
|
||||
new EthJsonRpcMethods(
|
||||
blockchainQueries,
|
||||
synchronizer,
|
||||
@@ -159,7 +163,8 @@ public class JsonRpcMethodsFactory {
|
||||
protocolContext,
|
||||
apiConfiguration,
|
||||
transactionSimulator,
|
||||
metricsSystem),
|
||||
metricsSystem,
|
||||
ethScheduler),
|
||||
new TxPoolJsonRpcMethods(transactionPool),
|
||||
new PluginsJsonRpcMethods(namedPlugins));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceTransacti
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
@@ -43,6 +44,7 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
private final ProtocolContext protocolContext;
|
||||
private final TransactionSimulator transactionSimulator;
|
||||
private final MetricsSystem metricsSystem;
|
||||
private final EthScheduler ethScheduler;
|
||||
|
||||
TraceJsonRpcMethods(
|
||||
final BlockchainQueries blockchainQueries,
|
||||
@@ -50,13 +52,15 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final ProtocolContext protocolContext,
|
||||
final ApiConfiguration apiConfiguration,
|
||||
final TransactionSimulator transactionSimulator,
|
||||
final MetricsSystem metricsSystem) {
|
||||
final MetricsSystem metricsSystem,
|
||||
final EthScheduler ethScheduler) {
|
||||
this.blockchainQueries = blockchainQueries;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.protocolContext = protocolContext;
|
||||
this.apiConfiguration = apiConfiguration;
|
||||
this.transactionSimulator = transactionSimulator;
|
||||
this.metricsSystem = metricsSystem;
|
||||
this.ethScheduler = ethScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,16 +73,18 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
|
||||
final BlockReplay blockReplay =
|
||||
new BlockReplay(protocolSchedule, protocolContext, blockchainQueries.getBlockchain());
|
||||
return mapOf(
|
||||
new TraceReplayBlockTransactions(protocolSchedule, blockchainQueries, metricsSystem),
|
||||
new TraceReplayBlockTransactions(
|
||||
protocolSchedule, blockchainQueries, metricsSystem, ethScheduler),
|
||||
new TraceFilter(
|
||||
protocolSchedule,
|
||||
blockchainQueries,
|
||||
apiConfiguration.getMaxTraceFilterRange(),
|
||||
metricsSystem),
|
||||
metricsSystem,
|
||||
ethScheduler),
|
||||
new TraceGet(() -> new BlockTracer(blockReplay), blockchainQueries, protocolSchedule),
|
||||
new TraceTransaction(
|
||||
() -> new BlockTracer(blockReplay), protocolSchedule, blockchainQueries),
|
||||
new TraceBlock(protocolSchedule, blockchainQueries, metricsSystem),
|
||||
new TraceBlock(protocolSchedule, blockchainQueries, metricsSystem, ethScheduler),
|
||||
new TraceCall(blockchainQueries, protocolSchedule, transactionSimulator),
|
||||
new TraceCallMany(blockchainQueries, protocolSchedule, transactionSimulator),
|
||||
new TraceRawTransaction(protocolSchedule, blockchainQueries, transactionSimulator));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -42,6 +42,7 @@ import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.eth.EthProtocol;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeers;
|
||||
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.p2p.network.P2PNetwork;
|
||||
@@ -214,7 +215,8 @@ public abstract class AbstractJsonRpcHttpServiceTest {
|
||||
syncVertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
transactionSimulator);
|
||||
transactionSimulator,
|
||||
new EthScheduler(1, 1, 1, new NoOpMetricsSystem()));
|
||||
}
|
||||
|
||||
protected void startService() throws Exception {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -45,6 +45,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
@@ -140,7 +141,8 @@ public class JsonRpcHttpServiceHostAllowlistTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
service = createJsonRpcHttpService();
|
||||
service.start().join();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
@@ -50,6 +50,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
@@ -171,7 +172,8 @@ public class JsonRpcHttpServiceLoginTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
service = createJsonRpcHttpService();
|
||||
jwtAuth = service.authenticationService.get().getJwtAuthProvider();
|
||||
service.start().join();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -55,6 +55,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Path;
|
||||
@@ -237,7 +238,8 @@ public class JsonRpcHttpServiceRpcApisTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
final JsonRpcHttpService jsonRpcHttpService =
|
||||
new JsonRpcHttpService(
|
||||
vertx,
|
||||
@@ -349,7 +351,8 @@ public class JsonRpcHttpServiceRpcApisTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
final JsonRpcHttpService jsonRpcHttpService =
|
||||
new JsonRpcHttpService(
|
||||
vertx,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -46,6 +46,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Path;
|
||||
@@ -149,7 +150,8 @@ public class JsonRpcHttpServiceTestBase {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
disabledRpcMethods = new HashMap<>();
|
||||
addedRpcMethods = new HashSet<>();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -52,6 +52,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -156,7 +157,8 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
|
||||
System.setProperty("javax.net.ssl.trustStore", CLIENT_AS_CA_CERT.getKeyStoreFile().toString());
|
||||
System.setProperty(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -51,6 +51,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
@@ -142,7 +143,8 @@ class JsonRpcHttpServiceTlsMisconfigurationTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -51,6 +51,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
@@ -143,7 +144,8 @@ public class JsonRpcHttpServiceTlsTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler());
|
||||
service = createJsonRpcHttpService(createJsonRpcConfig());
|
||||
service.start().join();
|
||||
baseUrl = service.url();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -15,65 +15,60 @@
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceFrame;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Answers;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class DebugTraceBlockByHashTest {
|
||||
|
||||
private final BlockTracer blockTracer = mock(BlockTracer.class);
|
||||
|
||||
private final BlockchainQueries blockchainQueries =
|
||||
mock(BlockchainQueries.class, Answers.RETURNS_DEEP_STUBS);
|
||||
private final MutableWorldState mutableWorldState = mock(MutableWorldState.class);
|
||||
private final BlockHeader blockHeader = mock(BlockHeader.class, Answers.RETURNS_DEEP_STUBS);
|
||||
private final DebugTraceBlockByHash debugTraceBlockByHash =
|
||||
new DebugTraceBlockByHash(() -> blockTracer, () -> blockchainQueries);
|
||||
|
||||
@Mock private ProtocolSchedule protocolSchedule;
|
||||
@Mock private BlockchainQueries blockchainQueries;
|
||||
@Mock private ObservableMetricsSystem metricsSystem;
|
||||
@Mock private Blockchain blockchain;
|
||||
@Mock private Block block;
|
||||
private DebugTraceBlockByHash debugTraceBlockByHash;
|
||||
private final Hash blockHash =
|
||||
Hash.fromHexString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
doAnswer(
|
||||
invocation ->
|
||||
invocation
|
||||
.<Function<MutableWorldState, Optional<? extends JsonRpcResponse>>>getArgument(
|
||||
1)
|
||||
.apply(mutableWorldState))
|
||||
.when(blockchainQueries)
|
||||
.getAndMapWorldState(any(), any());
|
||||
when(blockchainQueries.getBlockHeaderByHash(any(Hash.class)))
|
||||
.thenReturn(Optional.of(blockHeader));
|
||||
debugTraceBlockByHash =
|
||||
new DebugTraceBlockByHash(
|
||||
protocolSchedule, blockchainQueries, metricsSystem, new DeterministicEthScheduler());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -81,59 +76,54 @@ public class DebugTraceBlockByHashTest {
|
||||
assertThat(debugTraceBlockByHash.getName()).isEqualTo("debug_traceBlockByHash");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void shouldReturnCorrectResponse() {
|
||||
final Object[] params = new Object[] {blockHash};
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlockByHash", params));
|
||||
|
||||
final TraceFrame traceFrame =
|
||||
new TraceFrame(
|
||||
12,
|
||||
Optional.of("NONE"),
|
||||
Integer.MAX_VALUE,
|
||||
45L,
|
||||
OptionalLong.of(56L),
|
||||
0L,
|
||||
2,
|
||||
Optional.empty(),
|
||||
null,
|
||||
Wei.ZERO,
|
||||
Bytes.EMPTY,
|
||||
Bytes.EMPTY,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
null,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.empty(),
|
||||
false,
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
|
||||
when(blockchain.getBlockByHash(blockHash)).thenReturn(Optional.of(block));
|
||||
when(block.getHash()).thenReturn(blockHash);
|
||||
|
||||
final TransactionProcessingResult transaction1Result = mock(TransactionProcessingResult.class);
|
||||
final TransactionProcessingResult transaction2Result = mock(TransactionProcessingResult.class);
|
||||
DebugTraceTransactionResult result1 = mock(DebugTraceTransactionResult.class);
|
||||
DebugTraceTransactionResult result2 = mock(DebugTraceTransactionResult.class);
|
||||
|
||||
final TransactionTrace transaction1Trace = mock(TransactionTrace.class);
|
||||
final TransactionTrace transaction2Trace = mock(TransactionTrace.class);
|
||||
List<DebugTraceTransactionResult> resultList = Arrays.asList(result1, result2);
|
||||
|
||||
BlockTrace blockTrace = new BlockTrace(Arrays.asList(transaction1Trace, transaction2Trace));
|
||||
try (MockedStatic<Tracer> mockedTracer = mockStatic(Tracer.class)) {
|
||||
mockedTracer
|
||||
.when(
|
||||
() ->
|
||||
Tracer.processTracing(eq(blockchainQueries), eq(blockHash), any(Function.class)))
|
||||
.thenReturn(Optional.of(resultList));
|
||||
|
||||
when(transaction1Trace.getTraceFrames()).thenReturn(Arrays.asList(traceFrame));
|
||||
when(transaction2Trace.getTraceFrames()).thenReturn(Arrays.asList(traceFrame));
|
||||
when(transaction1Trace.getResult()).thenReturn(transaction1Result);
|
||||
when(transaction2Trace.getResult()).thenReturn(transaction2Result);
|
||||
when(transaction1Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(transaction2Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(blockTracer.trace(any(Tracer.TraceableState.class), eq(blockHash), any()))
|
||||
.thenReturn(Optional.of(blockTrace));
|
||||
final JsonRpcResponse jsonRpcResponse = debugTraceBlockByHash.response(request);
|
||||
assertThat(jsonRpcResponse).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) jsonRpcResponse;
|
||||
|
||||
final JsonRpcSuccessResponse response =
|
||||
(JsonRpcSuccessResponse) debugTraceBlockByHash.response(request);
|
||||
final Collection<?> result = (Collection<?>) response.getResult();
|
||||
assertThat(result).hasSize(2);
|
||||
final Collection<DebugTraceTransactionResult> traceResult = getResult(response);
|
||||
assertThat(traceResult).isNotEmpty();
|
||||
assertThat(traceResult).isInstanceOf(Collection.class).hasSize(2);
|
||||
assertThat(traceResult).containsExactly(result1, result2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Collection<DebugTraceTransactionResult> getResult(final JsonRpcSuccessResponse response) {
|
||||
return (Collection<DebugTraceTransactionResult>) response.getResult();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleInvalidParametersGracefully() {
|
||||
final Object[] invalidParams = new Object[] {"aaaa"};
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(
|
||||
new JsonRpcRequest("2.0", "debug_traceBlockByHash", invalidParams));
|
||||
|
||||
assertThatThrownBy(() -> debugTraceBlockByHash.response(request))
|
||||
.isInstanceOf(InvalidJsonRpcParameters.class)
|
||||
.hasMessageContaining("Invalid block hash parameter");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -14,131 +14,118 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceFrame;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Answers;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class DebugTraceBlockByNumberTest {
|
||||
|
||||
private final BlockchainQueries blockchainQueries =
|
||||
mock(BlockchainQueries.class, Answers.RETURNS_DEEP_STUBS);
|
||||
@Mock private BlockchainQueries blockchainQueries;
|
||||
@Mock private Blockchain blockchain;
|
||||
@Mock private Block block;
|
||||
@Mock private BlockHeader blockHeader;
|
||||
@Mock private ProtocolSchedule protocolSchedule;
|
||||
@Mock private ObservableMetricsSystem metricsSystem;
|
||||
private DebugTraceBlockByNumber debugTraceBlockByNumber;
|
||||
|
||||
private final Tracer.TraceableState worldState = mock(Tracer.TraceableState.class);
|
||||
private final BlockTracer blockTracer = mock(BlockTracer.class, Answers.RETURNS_DEEP_STUBS);
|
||||
private final DebugTraceBlockByNumber debugTraceBlockByNumber =
|
||||
new DebugTraceBlockByNumber(() -> blockTracer, blockchainQueries);
|
||||
|
||||
private final Hash blockHash =
|
||||
Hash.fromHexString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
debugTraceBlockByNumber =
|
||||
new DebugTraceBlockByNumber(
|
||||
protocolSchedule, blockchainQueries, metricsSystem, new DeterministicEthScheduler());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameShouldBeDebugTraceBlockByNumber() {
|
||||
assertThat(debugTraceBlockByNumber.getName()).isEqualTo("debug_traceBlockByNumber");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void shouldReturnCorrectResponse() {
|
||||
|
||||
final long blockNumber = 1L;
|
||||
final Object[] params = new Object[] {Long.toHexString(blockNumber)};
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlockByNumber", params));
|
||||
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
|
||||
when(blockchain.getBlockByNumber(blockNumber)).thenReturn(Optional.of(block));
|
||||
when(block.getHeader()).thenReturn(blockHeader);
|
||||
|
||||
final TraceFrame traceFrame =
|
||||
new TraceFrame(
|
||||
12,
|
||||
Optional.of("NONE"),
|
||||
Integer.MAX_VALUE,
|
||||
45L,
|
||||
OptionalLong.of(56L),
|
||||
0L,
|
||||
2,
|
||||
Optional.empty(),
|
||||
null,
|
||||
Wei.ZERO,
|
||||
Bytes.EMPTY,
|
||||
Bytes.EMPTY,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
null,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.empty(),
|
||||
false,
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
DebugTraceTransactionResult result1 = mock(DebugTraceTransactionResult.class);
|
||||
DebugTraceTransactionResult result2 = mock(DebugTraceTransactionResult.class);
|
||||
|
||||
final TransactionProcessingResult transaction1Result = mock(TransactionProcessingResult.class);
|
||||
final TransactionProcessingResult transaction2Result = mock(TransactionProcessingResult.class);
|
||||
List<DebugTraceTransactionResult> resultList = Arrays.asList(result1, result2);
|
||||
|
||||
final TransactionTrace transaction1Trace = mock(TransactionTrace.class);
|
||||
final TransactionTrace transaction2Trace = mock(TransactionTrace.class);
|
||||
try (MockedStatic<Tracer> mockedTracer = mockStatic(Tracer.class)) {
|
||||
mockedTracer
|
||||
.when(
|
||||
() ->
|
||||
Tracer.processTracing(
|
||||
eq(blockchainQueries), eq(Optional.of(blockHeader)), any(Function.class)))
|
||||
.thenReturn(Optional.of(resultList));
|
||||
|
||||
final BlockTrace blockTrace = new BlockTrace(asList(transaction1Trace, transaction2Trace));
|
||||
final JsonRpcResponse jsonRpcResponse = debugTraceBlockByNumber.response(request);
|
||||
assertThat(jsonRpcResponse).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) jsonRpcResponse;
|
||||
|
||||
when(transaction1Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
|
||||
when(transaction2Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
|
||||
when(transaction1Trace.getResult()).thenReturn(transaction1Result);
|
||||
when(transaction2Trace.getResult()).thenReturn(transaction2Result);
|
||||
when(transaction1Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(transaction2Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(blockchainQueries.getBlockHashByNumber(blockNumber)).thenReturn(Optional.of(blockHash));
|
||||
when(blockchainQueries.getBlockHeaderByHash(any(Hash.class)))
|
||||
.thenReturn(Optional.of(mock(BlockHeader.class, Answers.RETURNS_DEEP_STUBS)));
|
||||
|
||||
doAnswer(
|
||||
invocation ->
|
||||
invocation
|
||||
.<Function<MutableWorldState, ? extends Optional<? extends JsonRpcResponse>>>
|
||||
getArgument(1)
|
||||
.apply(worldState))
|
||||
.when(blockchainQueries)
|
||||
.getAndMapWorldState(any(), any());
|
||||
when(blockTracer.trace(any(Tracer.TraceableState.class), any(Hash.class), any()))
|
||||
.thenReturn(Optional.of(blockTrace));
|
||||
|
||||
final JsonRpcSuccessResponse response =
|
||||
(JsonRpcSuccessResponse) debugTraceBlockByNumber.response(request);
|
||||
final Collection<DebugTraceTransactionResult> result = getResult(response);
|
||||
assertThat(result)
|
||||
.usingFieldByFieldElementComparator()
|
||||
.isEqualTo(DebugTraceTransactionResult.of(blockTrace.getTransactionTraces()));
|
||||
final Collection<DebugTraceTransactionResult> traceResult = getResult(response);
|
||||
assertThat(traceResult).isNotEmpty();
|
||||
assertThat(traceResult).isInstanceOf(Collection.class).hasSize(2);
|
||||
assertThat(traceResult).containsExactly(result1, result2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Collection<DebugTraceTransactionResult> getResult(final JsonRpcSuccessResponse response) {
|
||||
return (Collection<DebugTraceTransactionResult>) response.getResult();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleInvalidParametersGracefully() {
|
||||
final Object[] invalidParams = new Object[] {"invalid-block-number"};
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(
|
||||
new JsonRpcRequest("2.0", "debug_traceBlockByNumber", invalidParams));
|
||||
|
||||
assertThatThrownBy(() -> debugTraceBlockByNumber.response(request))
|
||||
.isInstanceOf(InvalidJsonRpcParameters.class)
|
||||
.hasMessageContaining("Invalid block parameter");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright ConsenSys AG.
|
||||
* Copyright contributors to 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
|
||||
@@ -14,53 +14,114 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.config.GenesisConfig;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.Tracer;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionTrace;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockWithMetadata;
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTransactionResult;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
||||
import org.hyperledger.besu.ethereum.debug.TraceFrame;
|
||||
import org.hyperledger.besu.ethereum.core.ExecutionContextTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
||||
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
|
||||
import org.hyperledger.besu.ethereum.mainnet.TransactionValidatorFactory;
|
||||
import org.hyperledger.besu.ethereum.mainnet.WithdrawalsProcessor;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class DebugTraceBlockTest {
|
||||
@Mock private BlockchainQueries blockchainQueries;
|
||||
@Mock private Blockchain blockchain;
|
||||
@Mock private ObservableMetricsSystem metricsSystem;
|
||||
@Mock private WithdrawalsProcessor withdrawalsProcessor;
|
||||
@Mock private TransactionValidatorFactory alwaysValidTransactionValidatorFactory;
|
||||
private DebugTraceBlock debugTraceBlock;
|
||||
|
||||
private final BlockTracer blockTracer = mock(BlockTracer.class);
|
||||
private final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class);
|
||||
private final DebugTraceBlock debugTraceBlock =
|
||||
new DebugTraceBlock(() -> blockTracer, new MainnetBlockHeaderFunctions(), blockchainQueries);
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
// As we build the block from RLP in DebugTraceBlock, we need to have non mocked
|
||||
// protocolSchedule (and ProtocolSpec)
|
||||
// to be able to get the hash of the block
|
||||
final var genesisConfig =
|
||||
GenesisConfig.fromResource(
|
||||
"/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data/genesis.json");
|
||||
final ProtocolSpecAdapters protocolSpecAdapters =
|
||||
ProtocolSpecAdapters.create(
|
||||
0,
|
||||
specBuilder -> {
|
||||
specBuilder.isReplayProtectionSupported(true);
|
||||
specBuilder.withdrawalsProcessor(withdrawalsProcessor);
|
||||
specBuilder.transactionValidatorFactoryBuilder(
|
||||
(evm, gasLimitCalculator, feeMarket) -> alwaysValidTransactionValidatorFactory);
|
||||
return specBuilder;
|
||||
});
|
||||
final ExecutionContextTestFixture executionContextTestFixture =
|
||||
ExecutionContextTestFixture.builder(genesisConfig)
|
||||
.protocolSchedule(
|
||||
new ProtocolScheduleBuilder(
|
||||
genesisConfig.getConfigOptions(),
|
||||
Optional.of(BigInteger.valueOf(42)),
|
||||
protocolSpecAdapters,
|
||||
PrivacyParameters.DEFAULT,
|
||||
false,
|
||||
EvmConfiguration.DEFAULT,
|
||||
MiningConfiguration.MINING_DISABLED,
|
||||
new BadBlockManager(),
|
||||
false,
|
||||
new NoOpMetricsSystem())
|
||||
.createProtocolSchedule())
|
||||
.build();
|
||||
debugTraceBlock =
|
||||
new DebugTraceBlock(
|
||||
executionContextTestFixture.getProtocolSchedule(),
|
||||
blockchainQueries,
|
||||
metricsSystem,
|
||||
new DeterministicEthScheduler());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nameShouldBeDebugTraceBlock() {
|
||||
assertThat(debugTraceBlock.getName()).isEqualTo("debug_traceBlock");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void shouldReturnCorrectResponse() {
|
||||
final Block parentBlock =
|
||||
@@ -79,71 +140,37 @@ public class DebugTraceBlockTest {
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlock", params));
|
||||
|
||||
final TraceFrame traceFrame =
|
||||
new TraceFrame(
|
||||
12,
|
||||
Optional.of("NONE"),
|
||||
Integer.MAX_VALUE,
|
||||
45L,
|
||||
OptionalLong.of(56L),
|
||||
0L,
|
||||
2,
|
||||
Optional.empty(),
|
||||
null,
|
||||
Wei.ZERO,
|
||||
Bytes.EMPTY,
|
||||
Bytes.EMPTY,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
null,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.empty(),
|
||||
false,
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
|
||||
when(blockchain.getBlockByHash(block.getHeader().getParentHash()))
|
||||
.thenReturn(Optional.of(parentBlock));
|
||||
|
||||
final TransactionProcessingResult transaction1Result = mock(TransactionProcessingResult.class);
|
||||
final TransactionProcessingResult transaction2Result = mock(TransactionProcessingResult.class);
|
||||
DebugTraceTransactionResult result1 = mock(DebugTraceTransactionResult.class);
|
||||
DebugTraceTransactionResult result2 = mock(DebugTraceTransactionResult.class);
|
||||
|
||||
final TransactionTrace transaction1Trace = mock(TransactionTrace.class);
|
||||
final TransactionTrace transaction2Trace = mock(TransactionTrace.class);
|
||||
List<DebugTraceTransactionResult> resultList = Arrays.asList(result1, result2);
|
||||
|
||||
final BlockTrace blockTrace = new BlockTrace(asList(transaction1Trace, transaction2Trace));
|
||||
try (MockedStatic<Tracer> mockedTracer = mockStatic(Tracer.class)) {
|
||||
mockedTracer
|
||||
.when(
|
||||
() ->
|
||||
Tracer.processTracing(
|
||||
eq(blockchainQueries), eq(block.getHash()), any(Function.class)))
|
||||
.thenReturn(Optional.of(resultList));
|
||||
|
||||
when(transaction1Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
|
||||
when(transaction2Trace.getTraceFrames()).thenReturn(singletonList(traceFrame));
|
||||
when(transaction1Trace.getResult()).thenReturn(transaction1Result);
|
||||
when(transaction2Trace.getResult()).thenReturn(transaction2Result);
|
||||
when(transaction1Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(transaction2Result.getOutput()).thenReturn(Bytes.fromHexString("1234"));
|
||||
when(blockTracer.trace(any(Tracer.TraceableState.class), eq(block), any()))
|
||||
.thenReturn(Optional.of(blockTrace));
|
||||
final JsonRpcResponse jsonRpcResponse = debugTraceBlock.response(request);
|
||||
assertThat(jsonRpcResponse).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) jsonRpcResponse;
|
||||
|
||||
when(blockchainQueries.blockByHash(parentBlock.getHash()))
|
||||
.thenReturn(
|
||||
Optional.of(
|
||||
new BlockWithMetadata<>(
|
||||
parentBlock.getHeader(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
parentBlock.getHeader().getDifficulty(),
|
||||
parentBlock.calculateSize())));
|
||||
when(blockchainQueries.getAndMapWorldState(eq(parentBlock.getHash()), any()))
|
||||
.thenAnswer(
|
||||
invocationOnMock -> {
|
||||
Function<Tracer.TraceableState, ? extends Optional<BlockTracer>> mapper =
|
||||
invocationOnMock.getArgument(1);
|
||||
return mapper.apply(mock(Tracer.TraceableState.class));
|
||||
});
|
||||
final Collection<DebugTraceTransactionResult> traceResult = getResult(response);
|
||||
assertThat(traceResult).isNotEmpty();
|
||||
assertThat(traceResult).isInstanceOf(Collection.class).hasSize(2);
|
||||
assertThat(traceResult).containsExactly(result1, result2);
|
||||
}
|
||||
}
|
||||
|
||||
final JsonRpcSuccessResponse response =
|
||||
(JsonRpcSuccessResponse) debugTraceBlock.response(request);
|
||||
final Collection<?> result = (Collection<?>) response.getResult();
|
||||
assertThat(result).hasSize(2);
|
||||
@SuppressWarnings("unchecked")
|
||||
private Collection<DebugTraceTransactionResult> getResult(final JsonRpcSuccessResponse response) {
|
||||
return (Collection<DebugTraceTransactionResult>) response.getResult();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,9 +185,26 @@ public class DebugTraceBlockTest {
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlock", params));
|
||||
|
||||
when(blockchainQueries.blockByHash(any())).thenReturn(Optional.empty());
|
||||
when(blockchainQueries.getBlockchain()).thenReturn(blockchain);
|
||||
when(blockchain.getBlockByHash(block.getHeader().getParentHash())).thenReturn(Optional.empty());
|
||||
|
||||
final JsonRpcResponse jsonRpcResponse = debugTraceBlock.response(request);
|
||||
assertThat(jsonRpcResponse).isInstanceOf(JsonRpcErrorResponse.class);
|
||||
final JsonRpcErrorResponse response = (JsonRpcErrorResponse) debugTraceBlock.response(request);
|
||||
|
||||
assertThat(response.getErrorType()).isEqualByComparingTo(RpcErrorType.PARENT_BLOCK_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleInvalidParametersGracefully() {
|
||||
final Object[] invalidParams = new Object[] {"invalid RLP"};
|
||||
final JsonRpcRequestContext request =
|
||||
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "debug_traceBlock", invalidParams));
|
||||
|
||||
final JsonRpcResponse jsonRpcResponse = debugTraceBlock.response(request);
|
||||
assertThat(jsonRpcResponse).isInstanceOf(JsonRpcErrorResponse.class);
|
||||
final JsonRpcErrorResponse response = (JsonRpcErrorResponse) debugTraceBlock.response(request);
|
||||
|
||||
assertThat(response.getError().getMessage()).contains("Invalid block, unable to parse RLP");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,10 +165,10 @@ public class DebugTraceTransactionTest {
|
||||
assertThat(transactionResult.getStructLogs().size()).isEqualTo(1);
|
||||
assertThat(transactionResult.getStructLogs().get(0).stack().length).isEqualTo(1);
|
||||
assertThat(transactionResult.getStructLogs().get(0).stack()[0])
|
||||
.isEqualTo(stackBytes[0].toUnprefixedHexString());
|
||||
.isEqualTo(StructLog.toCompactHex(stackBytes[0], true));
|
||||
assertThat(transactionResult.getStructLogs().get(0).memory().length).isEqualTo(1);
|
||||
assertThat(transactionResult.getStructLogs().get(0).memory()[0])
|
||||
.isEqualTo(memoryBytes[0].toUnprefixedHexString());
|
||||
.isEqualTo(StructLog.toCompactHex(memoryBytes[0], true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.hyperledger.besu.ethereum.transaction.PreCloseStateHandler;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
@@ -123,6 +124,33 @@ public class EthCallTest {
|
||||
assertThat(overrideMap).containsValue(override);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fullStateOverrides() {
|
||||
StateOverrideMap suppliedOverrides = new StateOverrideMap();
|
||||
StateOverride override =
|
||||
new StateOverride.Builder()
|
||||
.withNonce(new UnsignedLongParameter("0x9e"))
|
||||
.withBalance(Wei.of(100))
|
||||
.withCode("0x1234")
|
||||
.withStateDiff(Map.of("0x1234", "0x5678"))
|
||||
.withMovePrecompileToAddress(Address.fromHexString("0x1234"))
|
||||
.build();
|
||||
final Address address = Address.fromHexString("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3");
|
||||
suppliedOverrides.put(address, override);
|
||||
|
||||
final JsonRpcRequestContext request =
|
||||
ethCallRequestWithStateOverrides(callParameter(), "latest", suppliedOverrides);
|
||||
|
||||
Optional<StateOverrideMap> maybeOverrideMap = method.getAddressStateOverrideMap(request);
|
||||
assertThat(maybeOverrideMap.isPresent()).isTrue();
|
||||
StateOverrideMap actualOverrideMap = maybeOverrideMap.get();
|
||||
assertThat(actualOverrideMap.keySet()).hasSize(1);
|
||||
assertThat(actualOverrideMap.values()).hasSize(1);
|
||||
|
||||
assertThat(actualOverrideMap).containsKey(address);
|
||||
assertThat(actualOverrideMap).containsValue(override);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnInternalErrorWhenProcessorReturnsEmpty() {
|
||||
final JsonRpcRequestContext request = ethCallRequest(callParameter(), "latest");
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
|
||||
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -71,7 +72,11 @@ public class TraceFilterTest {
|
||||
|
||||
method =
|
||||
new TraceFilter(
|
||||
protocolSchedule, blockchainQueries, maxFilterRange, new NoOpMetricsSystem());
|
||||
protocolSchedule,
|
||||
blockchainQueries,
|
||||
maxFilterRange,
|
||||
new NoOpMetricsSystem(),
|
||||
new DeterministicEthScheduler());
|
||||
|
||||
final JsonRpcResponse response = method.response(request);
|
||||
assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
|
||||
|
||||
@@ -147,7 +147,8 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
|
||||
final List<String> requestsWithoutRequestId =
|
||||
requests.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.map(Request::getEncodedRequest)
|
||||
.map(Bytes::toHexString)
|
||||
.toList();
|
||||
Optional.of(resp)
|
||||
.map(JsonRpcSuccessResponse.class::cast)
|
||||
@@ -172,6 +173,53 @@ public class EngineGetPayloadV4Test extends AbstractEngineGetPayloadTest {
|
||||
verify(engineCallListener, times(1)).executionEngineCalled();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExcludeEmptyRequestsInRequestsList() {
|
||||
|
||||
BlockHeader header =
|
||||
new BlockHeaderTestFixture().timestamp(pragueHardfork.milestone() + 1).buildHeader();
|
||||
PayloadIdentifier payloadIdentifier =
|
||||
PayloadIdentifier.forPayloadParams(
|
||||
Hash.ZERO,
|
||||
pragueHardfork.milestone(),
|
||||
Bytes32.random(),
|
||||
Address.fromHexString("0x42"),
|
||||
Optional.empty(),
|
||||
Optional.empty());
|
||||
|
||||
BlockWithReceipts block =
|
||||
new BlockWithReceipts(
|
||||
new Block(header, new BlockBody(emptyList(), emptyList(), Optional.of(emptyList()))),
|
||||
emptyList());
|
||||
final List<Request> unorderedRequests =
|
||||
List.of(
|
||||
new Request(RequestType.CONSOLIDATION, Bytes.of(1)),
|
||||
new Request(RequestType.DEPOSIT, Bytes.of(1)),
|
||||
new Request(RequestType.WITHDRAWAL, Bytes.EMPTY));
|
||||
PayloadWrapper payload =
|
||||
new PayloadWrapper(payloadIdentifier, block, Optional.of(unorderedRequests));
|
||||
|
||||
when(mergeContext.retrievePayloadById(payloadIdentifier)).thenReturn(Optional.of(payload));
|
||||
|
||||
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V4.getMethodName(), payloadIdentifier);
|
||||
assertThat(resp).isInstanceOf(JsonRpcSuccessResponse.class);
|
||||
|
||||
final List<String> expectedRequests =
|
||||
List.of(
|
||||
Bytes.concatenate(Bytes.of(RequestType.DEPOSIT.getSerializedType()), Bytes.of(1))
|
||||
.toHexString(),
|
||||
Bytes.concatenate(Bytes.of(RequestType.CONSOLIDATION.getSerializedType()), Bytes.of(1))
|
||||
.toHexString());
|
||||
Optional.of(resp)
|
||||
.map(JsonRpcSuccessResponse.class::cast)
|
||||
.ifPresent(
|
||||
r -> {
|
||||
assertThat(r.getResult()).isInstanceOf(EngineGetPayloadResultV4.class);
|
||||
final EngineGetPayloadResultV4 res = (EngineGetPayloadResultV4) r.getResult();
|
||||
assertThat(res.getExecutionRequests()).isEqualTo(expectedRequests);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnUnsupportedFork() {
|
||||
final var resp = resp(RpcMethod.ENGINE_GET_PAYLOAD_V4.getMethodName(), mockPid);
|
||||
|
||||
@@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.INVALID_BLOCK_HASH;
|
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -43,7 +44,8 @@ public class EngineNewPayloadV1Test extends AbstractEngineNewPayloadTest {
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener);
|
||||
engineCallListener,
|
||||
new NoOpMetricsSystem());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Withdrawal;
|
||||
import org.hyperledger.besu.ethereum.mainnet.WithdrawalsValidator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -64,7 +65,8 @@ public class EngineNewPayloadV2Test extends AbstractEngineNewPayloadTest {
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener);
|
||||
engineCallListener,
|
||||
new NoOpMetricsSystem());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
|
||||
import org.hyperledger.besu.ethereum.mainnet.CancunTargetingGasLimitCalculator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
@@ -95,7 +96,8 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener);
|
||||
engineCallListener,
|
||||
new NoOpMetricsSystem());
|
||||
lenient().when(protocolSpec.getGasCalculator()).thenReturn(new CancunGasCalculator());
|
||||
lenient()
|
||||
.when(protocolSpec.getGasLimitCalculator())
|
||||
@@ -120,7 +122,8 @@ public class EngineNewPayloadV3Test extends EngineNewPayloadV2Test {
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener);
|
||||
engineCallListener,
|
||||
new NoOpMetricsSystem());
|
||||
final JsonRpcResponse badParam =
|
||||
methodV3.response(
|
||||
new JsonRpcRequestContext(
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.hyperledger.besu.ethereum.mainnet.BodyValidation;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.MainnetRequestsValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.requests.ProhibitedRequestValidator;
|
||||
import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -78,7 +79,8 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
protocolContext,
|
||||
mergeCoordinator,
|
||||
ethPeers,
|
||||
engineCallListener);
|
||||
engineCallListener,
|
||||
new NoOpMetricsSystem());
|
||||
lenient().when(protocolSchedule.hardforkFor(any())).thenReturn(Optional.of(pragueHardfork));
|
||||
lenient().when(protocolSpec.getGasCalculator()).thenReturn(new PragueGasCalculator());
|
||||
mockAllowedRequestsValidator();
|
||||
@@ -168,7 +170,10 @@ public class EngineNewPayloadV4Test extends EngineNewPayloadV3Test {
|
||||
final List<String> requestsWithoutRequestId =
|
||||
VALID_REQUESTS.stream()
|
||||
.sorted(Comparator.comparing(Request::getType))
|
||||
.map(r -> r.getData().toHexString())
|
||||
.map(
|
||||
r ->
|
||||
Bytes.concatenate(Bytes.of(r.getType().getSerializedType()), r.getData())
|
||||
.toHexString())
|
||||
.toList();
|
||||
Object[] params =
|
||||
maybeParentBeaconBlockRoot
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright contributors to 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.api.jsonrpc.internal.results;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.ethereum.debug.TraceFrame;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class StructLogTest {
|
||||
|
||||
@Mock private TraceFrame traceFrame;
|
||||
|
||||
private StructLog structLog;
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorShouldInitializeFields() throws Exception {
|
||||
// Given
|
||||
final String op = "PUSH1";
|
||||
final int depth = 0;
|
||||
final long gas = 100L;
|
||||
final OptionalLong gasCost = OptionalLong.of(10L);
|
||||
final String[] memory =
|
||||
new String[] {"0x01", "0x02", "0x0003", "0x04", "0x00000005", "0x000000"};
|
||||
final String[] stack = new String[] {"0x00000000000000", "0x01", "0x000002", "0x03"};
|
||||
final Map<String, String> storage =
|
||||
Map.of(
|
||||
"0x01", "0x2233333",
|
||||
"0x02", "0x4455667");
|
||||
final String reason = "0x0001";
|
||||
|
||||
// Mock TraceFrame behaviors
|
||||
when(traceFrame.getDepth()).thenReturn(depth);
|
||||
when(traceFrame.getGasRemaining()).thenReturn(gas);
|
||||
when(traceFrame.getGasCost()).thenReturn(gasCost);
|
||||
when(traceFrame.getMemory())
|
||||
.thenReturn(
|
||||
Optional.of(
|
||||
Arrays.stream(memory)
|
||||
.map(Bytes::fromHexString) // Convert each string to Bytes
|
||||
.toArray(Bytes[]::new)));
|
||||
when(traceFrame.getOpcode()).thenReturn(op);
|
||||
when(traceFrame.getPc()).thenReturn(1);
|
||||
when(traceFrame.getStack())
|
||||
.thenReturn(
|
||||
Optional.of(
|
||||
Arrays.stream(stack)
|
||||
.map(Bytes::fromHexString) // Convert each string to Bytes
|
||||
.toArray(Bytes[]::new)));
|
||||
Map<UInt256, UInt256> storageMap = new HashMap<>();
|
||||
for (Map.Entry<String, String> entry : storage.entrySet()) {
|
||||
storageMap.put(
|
||||
UInt256.fromHexString(entry.getKey()), UInt256.fromHexString(entry.getValue()));
|
||||
}
|
||||
when(traceFrame.getStorage()).thenReturn(Optional.of(storageMap));
|
||||
when(traceFrame.getRevertReason()).thenReturn(Optional.of(Bytes.fromHexString(reason)));
|
||||
|
||||
// When
|
||||
structLog = new StructLog(traceFrame);
|
||||
|
||||
// Then
|
||||
assertThat(structLog.depth()).isEqualTo(depth + 1);
|
||||
assertThat(structLog.gas()).isEqualTo(gas);
|
||||
assertThat(structLog.gasCost()).isEqualTo(gasCost.getAsLong());
|
||||
assertThat(structLog.memory())
|
||||
.isEqualTo(new String[] {"0x1", "0x2", "0x3", "0x4", "0x5", "0x0"});
|
||||
assertThat(structLog.op()).isEqualTo(op);
|
||||
assertThat(structLog.pc()).isEqualTo(1);
|
||||
assertThat(structLog.stack()).isEqualTo(new String[] {"0x0", "0x1", "0x2", "0x3"});
|
||||
assertThat(structLog.storage())
|
||||
.isEqualTo(
|
||||
Map.of(
|
||||
"1", "2233333",
|
||||
"2", "4455667"));
|
||||
assertThat(structLog.reason()).isEqualTo("0x1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGenerateJsonCorrectly() throws Exception {
|
||||
final String op = "PUSH1";
|
||||
final int depth = 0;
|
||||
final long gas = 100L;
|
||||
final OptionalLong gasCost = OptionalLong.of(10L);
|
||||
final String[] memory =
|
||||
new String[] {"0x01", "0x02", "0x0023", "0x04", "0x000000e5", "0x000000"};
|
||||
final String[] stack = new String[] {"0x00000000000000", "0x01", "0x000002", "0x03"};
|
||||
final Map<String, String> storage =
|
||||
Map.of(
|
||||
"0x01", "0x2233333",
|
||||
"0x02", "0x4455667");
|
||||
final String reason = "0x53756e696665642066756e6473";
|
||||
|
||||
// Mock TraceFrame behaviors
|
||||
when(traceFrame.getDepth()).thenReturn(depth);
|
||||
when(traceFrame.getGasRemaining()).thenReturn(gas);
|
||||
when(traceFrame.getGasCost()).thenReturn(gasCost);
|
||||
when(traceFrame.getMemory())
|
||||
.thenReturn(
|
||||
Optional.of(
|
||||
Arrays.stream(memory)
|
||||
.map(Bytes::fromHexString) // Convert each string to Bytes
|
||||
.toArray(Bytes[]::new)));
|
||||
when(traceFrame.getOpcode()).thenReturn(op);
|
||||
when(traceFrame.getPc()).thenReturn(1);
|
||||
when(traceFrame.getStack())
|
||||
.thenReturn(
|
||||
Optional.of(
|
||||
Arrays.stream(stack)
|
||||
.map(Bytes::fromHexString) // Convert each string to Bytes
|
||||
.toArray(Bytes[]::new)));
|
||||
Map<UInt256, UInt256> storageMap = new HashMap<>();
|
||||
for (Map.Entry<String, String> entry : storage.entrySet()) {
|
||||
storageMap.put(
|
||||
UInt256.fromHexString(entry.getKey()), UInt256.fromHexString(entry.getValue()));
|
||||
}
|
||||
when(traceFrame.getStorage()).thenReturn(Optional.of(storageMap));
|
||||
when(traceFrame.getRevertReason()).thenReturn(Optional.of(Bytes.fromHexString(reason)));
|
||||
|
||||
// When
|
||||
structLog = new StructLog(traceFrame);
|
||||
|
||||
// Use Jackson to serialize the StructLog object to a JSON string
|
||||
String json = objectMapper.writeValueAsString(structLog);
|
||||
|
||||
// Define the expected JSON output
|
||||
String expectedJson =
|
||||
"{"
|
||||
+ "\"pc\":1,"
|
||||
+ "\"op\":\"PUSH1\","
|
||||
+ "\"gas\":100,"
|
||||
+ "\"gasCost\":10,"
|
||||
+ "\"depth\":1,"
|
||||
+ "\"stack\":[\"0x0\",\"0x1\",\"0x2\",\"0x3\"],"
|
||||
+ "\"memory\":[\"0x1\",\"0x2\",\"0x23\",\"0x4\",\"0xe5\",\"0x0\"],"
|
||||
+ "\"storage\":{\"1\":\"2233333\",\"2\":\"4455667\"},"
|
||||
+ "\"reason\":\"0x53756e696665642066756e6473\""
|
||||
+ "}";
|
||||
|
||||
// Then
|
||||
assertThat(json).isEqualTo(expectedJson); // Verify the generated JSON matches the expected JSON
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexEmptyWithPrefix() {
|
||||
Bytes emptyBytes = Bytes.EMPTY;
|
||||
String result = StructLog.toCompactHex(emptyBytes, true);
|
||||
assertEquals("0x0", result, "Expected '0x0' for an empty byte array with prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexEmptyWithoutPrefix() {
|
||||
Bytes emptyBytes = Bytes.EMPTY;
|
||||
String result = StructLog.toCompactHex(emptyBytes, false);
|
||||
assertEquals("0", result, "Expected '0' for an empty byte array without prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexSingleByteWithPrefix() {
|
||||
Bytes bytes = Bytes.fromHexString("0x01");
|
||||
String result = StructLog.toCompactHex(bytes, true);
|
||||
assertEquals("0x1", result, "Expected '0x1' for the byte 0x01 with prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexSingleByteWithoutPrefix() {
|
||||
Bytes bytes = Bytes.fromHexString("0x01");
|
||||
String result = StructLog.toCompactHex(bytes, false);
|
||||
assertEquals("1", result, "Expected '1' for the byte 0x01 without prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexMultipleBytesWithPrefix() {
|
||||
Bytes bytes = Bytes.fromHexString("0x010203");
|
||||
String result = StructLog.toCompactHex(bytes, true);
|
||||
assertEquals("0x10203", result, "Expected '0x10203' for the byte array 0x010203 with prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexMultipleBytesWithoutPrefix() {
|
||||
Bytes bytes = Bytes.fromHexString("0x010203");
|
||||
String result = StructLog.toCompactHex(bytes, false);
|
||||
assertEquals("10203", result, "Expected '10203' for the byte array 0x010203 without prefix");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexWithLeadingZeros() {
|
||||
Bytes bytes = Bytes.fromHexString("0x0001");
|
||||
String result = StructLog.toCompactHex(bytes, true);
|
||||
assertEquals(
|
||||
"0x1",
|
||||
result,
|
||||
"Expected '0x1' for the byte array 0x0001 with prefix (leading zeros removed)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToCompactHexWithLargeData() {
|
||||
Bytes bytes = Bytes.fromHexString("0x0102030405060708090a");
|
||||
String result = StructLog.toCompactHex(bytes, true);
|
||||
assertEquals("0x102030405060708090a", result, "Expected correct hex output for large data");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
* Copyright contributors to 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
|
||||
@@ -58,6 +58,7 @@ import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
|
||||
import org.hyperledger.besu.nat.NatService;
|
||||
import org.hyperledger.besu.testutil.DeterministicEthScheduler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.URISyntaxException;
|
||||
@@ -207,7 +208,8 @@ public class WebSocketServiceLoginTest {
|
||||
vertx,
|
||||
mock(ApiConfiguration.class),
|
||||
Optional.empty(),
|
||||
mock(TransactionSimulator.class)));
|
||||
mock(TransactionSimulator.class),
|
||||
new DeterministicEthScheduler()));
|
||||
|
||||
websocketMethods.putAll(rpcMethods);
|
||||
webSocketMessageHandlerSpy =
|
||||
|
||||
@@ -28,271 +28,163 @@
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493345,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : null,
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
{
|
||||
"request" : {
|
||||
"jsonrpc" : "2.0",
|
||||
"method" : "debug_traceCall",
|
||||
"params" : [ {
|
||||
"from" : "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
|
||||
"to" : "0x0050000000000000000000000000000000000000",
|
||||
"gas" : "0xfffff2",
|
||||
"gasPrice" : "0xef",
|
||||
"value" : "0x0",
|
||||
"data" : "0x0000000000000000000000000030000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001",
|
||||
"nonce" : "0x0"
|
||||
}, "latest" ],
|
||||
"id" : 1
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"gas" : 22070,
|
||||
"failed" : false,
|
||||
"returnValue" : "f000000000000000000000000000000000000000000000000000000000000002",
|
||||
"structLogs" : [ {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000040" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493345,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
} ]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"request" : {
|
||||
"jsonrpc" : "2.0",
|
||||
"method" : "debug_traceCall",
|
||||
"params" : [ {
|
||||
"from" : "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
|
||||
"to" : "0x0050000000000000000000000000000000000000",
|
||||
"gas" : "0xfffff2",
|
||||
"gasPrice" : "0xef",
|
||||
"value" : "0x0",
|
||||
"data" : "0x0000000000000000000000000030000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001",
|
||||
"nonce" : "0x0"
|
||||
}, "latest" ],
|
||||
"id" : 1
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"gas" : 22070,
|
||||
"failed" : false,
|
||||
"returnValue" : "f000000000000000000000000000000000000000000000000000000000000002",
|
||||
"structLogs" : [ {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20" ]
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x40" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0" ]
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x0" ]
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000" ]
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000", "0xffac99" ]
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0x0" ]
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001", "0x1" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002", "0x0" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493345,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0x20" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x1" ]
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x1", "0x20" ]
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x1", "0x20", "0x0" ]
|
||||
} ]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -29,270 +29,189 @@
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20" ]
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000040" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x40" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0" ]
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x0" ]
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000" ]
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000", "0xffac99" ]
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x0" ]
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001", "0x1" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002", "0x0" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493345,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x1" ]
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x1", "0x20" ]
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : null,
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"stack" : [ "0x1", "0x20", "0x0" ]
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -28,271 +28,177 @@
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 1
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"depth" : 2
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493345,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : null,
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : { },
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,210 +29,155 @@
|
||||
"gas" : 16755910,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755907,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20" ]
|
||||
}, {
|
||||
"pc" : 4,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755904,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "CALLDATASIZE",
|
||||
"gas" : 16755901,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 7,
|
||||
"op" : "SUB",
|
||||
"gas" : 16755899,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000040" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x40" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "DUP1",
|
||||
"gas" : 16755896,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755893,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755890,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "CALLDATACOPY",
|
||||
"gas" : 16755887,
|
||||
"gasCost" : 9,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x20", "0x20", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 14,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 16,
|
||||
"op" : "CALLVALUE",
|
||||
"gas" : 16755875,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 17,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755873,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 19,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16755870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 20,
|
||||
"op" : "GAS",
|
||||
"gas" : 16755867,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 21,
|
||||
"op" : "CALLCODE",
|
||||
"gas" : 16755865,
|
||||
"gasCost" : 16494066,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0", "0x20", "0x0", "0x0", "0x30000000000000000000000000000000000000", "0xffac99" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493366,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 16493363,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x0" ]
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493360,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001" ]
|
||||
}, {
|
||||
"pc" : 5,
|
||||
"op" : "ADD",
|
||||
"gas" : 16493357,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000001", "0x1" ]
|
||||
}, {
|
||||
"pc" : 6,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493354,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"memory" : [ ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 8,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 16493351,
|
||||
"gasCost" : 6,
|
||||
"depth" : 2,
|
||||
"stack" : [ "f000000000000000000000000000000000000000000000000000000000000002", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0xf000000000000000000000000000000000000000000000000000000000000002", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 9,
|
||||
"op" : "PUSH1",
|
||||
@@ -240,59 +185,47 @@
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 11,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16493342,
|
||||
"gasCost" : 3,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 13,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16493339,
|
||||
"gasCost" : 0,
|
||||
"depth" : 2,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x20", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 22,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755138,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x1" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 24,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 16755135,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x1", "0x20" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
}, {
|
||||
"pc" : 26,
|
||||
"op" : "RETURN",
|
||||
"gas" : 16755132,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000" ],
|
||||
"memory" : [ "f000000000000000000000000000000000000000000000000000000000000002" ],
|
||||
"storage" : null,
|
||||
"reason" : null
|
||||
"stack" : [ "0x1", "0x20", "0x0" ],
|
||||
"memory" : [ "0xf000000000000000000000000000000000000000000000000000000000000002" ]
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -20,22 +20,16 @@
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"gas": 21164,
|
||||
"failed": false,
|
||||
"returnValue": "",
|
||||
"structLogs": [
|
||||
{
|
||||
"pc": 0,
|
||||
"op": "STOP",
|
||||
"gas": 17592186023252,
|
||||
"gasCost": 0,
|
||||
"depth": 1,
|
||||
"stack": null,
|
||||
"memory": null,
|
||||
"storage": null,
|
||||
"reason": null
|
||||
}
|
||||
]
|
||||
"gas" : 21164,
|
||||
"failed" : false,
|
||||
"returnValue" : "",
|
||||
"structLogs" : [ {
|
||||
"pc" : 0,
|
||||
"op" : "STOP",
|
||||
"gas" : 17592186023252,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1
|
||||
} ]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,764 @@
|
||||
{
|
||||
"request": {
|
||||
"id": 1,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "debug_traceTransaction",
|
||||
"params": [
|
||||
"0xcef53f2311d7c80e9086d661e69ac11a5f3d081e28e02a9ba9b66749407ac310"
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"gas" : 23705,
|
||||
"failed" : false,
|
||||
"returnValue" : "",
|
||||
"structLogs" : [ {
|
||||
"pc" : 0,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292887,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ ]
|
||||
}, {
|
||||
"pc" : 2,
|
||||
"op" : "CALLDATALOAD",
|
||||
"gas" : 292884,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x0" ]
|
||||
}, {
|
||||
"pc" : 3,
|
||||
"op" : "PUSH29",
|
||||
"gas" : 292881,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f500000000000000000000000000000000000000000000000000000000" ]
|
||||
}, {
|
||||
"pc" : 33,
|
||||
"op" : "SWAP1",
|
||||
"gas" : 292878,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f500000000000000000000000000000000000000000000000000000000", "0x100000000000000000000000000000000000000000000000000000000" ]
|
||||
}, {
|
||||
"pc" : 34,
|
||||
"op" : "DIV",
|
||||
"gas" : 292875,
|
||||
"gasCost" : 5,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x100000000000000000000000000000000000000000000000000000000", "0x9dc2c8f500000000000000000000000000000000000000000000000000000000" ]
|
||||
}, {
|
||||
"pc" : 35,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292870,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 36,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292867,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 41,
|
||||
"op" : "EQ",
|
||||
"gas" : 292864,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x102accc1" ]
|
||||
}, {
|
||||
"pc" : 42,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292861,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 45,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292858,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x12c" ]
|
||||
}, {
|
||||
"pc" : 46,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292848,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 47,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292845,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 52,
|
||||
"op" : "EQ",
|
||||
"gas" : 292842,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x12a7b914" ]
|
||||
}, {
|
||||
"pc" : 53,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292839,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 56,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292836,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x13a" ]
|
||||
}, {
|
||||
"pc" : 57,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292826,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 58,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292823,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 63,
|
||||
"op" : "EQ",
|
||||
"gas" : 292820,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x1774e646" ]
|
||||
}, {
|
||||
"pc" : 64,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292817,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 67,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292814,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x14c" ]
|
||||
}, {
|
||||
"pc" : 68,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292804,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 69,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292801,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 74,
|
||||
"op" : "EQ",
|
||||
"gas" : 292798,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x1e26fd33" ]
|
||||
}, {
|
||||
"pc" : 75,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292795,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 78,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292792,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x15d" ]
|
||||
}, {
|
||||
"pc" : 79,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292782,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 80,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292779,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 85,
|
||||
"op" : "EQ",
|
||||
"gas" : 292776,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x1f903037" ]
|
||||
}, {
|
||||
"pc" : 86,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292773,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 89,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292770,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x16e" ]
|
||||
}, {
|
||||
"pc" : 90,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292760,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 91,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292757,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 96,
|
||||
"op" : "EQ",
|
||||
"gas" : 292754,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x343a875d" ]
|
||||
}, {
|
||||
"pc" : 97,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292751,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 100,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292748,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x180" ]
|
||||
}, {
|
||||
"pc" : 101,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292738,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 102,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292735,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 107,
|
||||
"op" : "EQ",
|
||||
"gas" : 292732,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x38cc4831" ]
|
||||
}, {
|
||||
"pc" : 108,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292729,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 111,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292726,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x195" ]
|
||||
}, {
|
||||
"pc" : 112,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292716,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 113,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292713,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 118,
|
||||
"op" : "EQ",
|
||||
"gas" : 292710,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x4e7ad367" ]
|
||||
}, {
|
||||
"pc" : 119,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292707,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 122,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292704,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x1bd" ]
|
||||
}, {
|
||||
"pc" : 123,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292694,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 124,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292691,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 129,
|
||||
"op" : "EQ",
|
||||
"gas" : 292688,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x57cb2fc4" ]
|
||||
}, {
|
||||
"pc" : 130,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292685,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 133,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292682,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x1cb" ]
|
||||
}, {
|
||||
"pc" : 134,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292672,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 135,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292669,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 140,
|
||||
"op" : "EQ",
|
||||
"gas" : 292666,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x65538c73" ]
|
||||
}, {
|
||||
"pc" : 141,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292663,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 144,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292660,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x1e0" ]
|
||||
}, {
|
||||
"pc" : 145,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292650,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 146,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292647,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 151,
|
||||
"op" : "EQ",
|
||||
"gas" : 292644,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x68895979" ]
|
||||
}, {
|
||||
"pc" : 152,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292641,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 155,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292638,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x1ee" ]
|
||||
}, {
|
||||
"pc" : 156,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292628,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 157,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292625,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 162,
|
||||
"op" : "EQ",
|
||||
"gas" : 292622,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x76bc21d9" ]
|
||||
}, {
|
||||
"pc" : 163,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292619,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 166,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292616,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x200" ]
|
||||
}, {
|
||||
"pc" : 167,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292606,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 168,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292603,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 173,
|
||||
"op" : "EQ",
|
||||
"gas" : 292600,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x9a19a953" ]
|
||||
}, {
|
||||
"pc" : 174,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292597,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 177,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292594,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x20e" ]
|
||||
}, {
|
||||
"pc" : 178,
|
||||
"op" : "DUP1",
|
||||
"gas" : 292584,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 179,
|
||||
"op" : "PUSH4",
|
||||
"gas" : 292581,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 184,
|
||||
"op" : "EQ",
|
||||
"gas" : 292578,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x9dc2c8f5", "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 185,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292575,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x1" ]
|
||||
}, {
|
||||
"pc" : 188,
|
||||
"op" : "JUMPI",
|
||||
"gas" : 292572,
|
||||
"gasCost" : 10,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x1", "0x21f" ]
|
||||
}, {
|
||||
"pc" : 543,
|
||||
"op" : "JUMPDEST",
|
||||
"gas" : 292562,
|
||||
"gasCost" : 1,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 544,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292561,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 547,
|
||||
"op" : "PUSH2",
|
||||
"gas" : 292558,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227" ]
|
||||
}, {
|
||||
"pc" : 550,
|
||||
"op" : "JUMP",
|
||||
"gas" : 292555,
|
||||
"gasCost" : 8,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0x693" ]
|
||||
}, {
|
||||
"pc" : 1683,
|
||||
"op" : "JUMPDEST",
|
||||
"gas" : 292547,
|
||||
"gasCost" : 1,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227" ]
|
||||
}, {
|
||||
"pc" : 1684,
|
||||
"op" : "PUSH32",
|
||||
"gas" : 292546,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227" ]
|
||||
}, {
|
||||
"pc" : 1717,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292543,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ]
|
||||
}, {
|
||||
"pc" : 1719,
|
||||
"op" : "MUL",
|
||||
"gas" : 292540,
|
||||
"gasCost" : 5,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0x1" ]
|
||||
}, {
|
||||
"pc" : 1720,
|
||||
"op" : "CALLER",
|
||||
"gas" : 292535,
|
||||
"gasCost" : 2,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ]
|
||||
}, {
|
||||
"pc" : 1721,
|
||||
"op" : "PUSH20",
|
||||
"gas" : 292533,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" ]
|
||||
}, {
|
||||
"pc" : 1742,
|
||||
"op" : "AND",
|
||||
"gas" : 292530,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0xffffffffffffffffffffffffffffffffffffffff" ]
|
||||
}, {
|
||||
"pc" : 1743,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292527,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" ]
|
||||
}, {
|
||||
"pc" : 1745,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292524,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1" ]
|
||||
}, {
|
||||
"pc" : 1747,
|
||||
"op" : "PUSH32",
|
||||
"gas" : 292521,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x0" ]
|
||||
}, {
|
||||
"pc" : 1780,
|
||||
"op" : "DUP2",
|
||||
"gas" : 292518,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x0", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9" ]
|
||||
}, {
|
||||
"pc" : 1781,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 292515,
|
||||
"gasCost" : 6,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x0", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9", "0x0" ]
|
||||
}, {
|
||||
"pc" : 1782,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292509,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x0" ]
|
||||
}, {
|
||||
"pc" : 1784,
|
||||
"op" : "ADD",
|
||||
"gas" : 292506,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x0", "0x20" ]
|
||||
}, {
|
||||
"pc" : 1785,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292503,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x20" ]
|
||||
}, {
|
||||
"pc" : 1787,
|
||||
"op" : "DUP2",
|
||||
"gas" : 292500,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x20", "0x2a" ]
|
||||
}, {
|
||||
"pc" : 1788,
|
||||
"op" : "MSTORE",
|
||||
"gas" : 292497,
|
||||
"gasCost" : 6,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x20", "0x2a", "0x20" ]
|
||||
}, {
|
||||
"pc" : 1789,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292491,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x20" ]
|
||||
}, {
|
||||
"pc" : 1791,
|
||||
"op" : "ADD",
|
||||
"gas" : 292488,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x20", "0x20" ]
|
||||
}, {
|
||||
"pc" : 1792,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 292485,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x40" ]
|
||||
}, {
|
||||
"pc" : 1794,
|
||||
"op" : "LOG3",
|
||||
"gas" : 292482,
|
||||
"gasCost" : 2012,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x1", "0x40", "0x0" ]
|
||||
}, {
|
||||
"pc" : 1795,
|
||||
"op" : "JUMPDEST",
|
||||
"gas" : 290470,
|
||||
"gasCost" : 1,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227" ]
|
||||
}, {
|
||||
"pc" : 1796,
|
||||
"op" : "JUMP",
|
||||
"gas" : 290469,
|
||||
"gasCost" : 8,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x227" ]
|
||||
}, {
|
||||
"pc" : 551,
|
||||
"op" : "JUMPDEST",
|
||||
"gas" : 290461,
|
||||
"gasCost" : 1,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 552,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 290460,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5" ]
|
||||
}, {
|
||||
"pc" : 554,
|
||||
"op" : "PUSH1",
|
||||
"gas" : 290457,
|
||||
"gasCost" : 3,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0" ]
|
||||
}, {
|
||||
"pc" : 556,
|
||||
"op" : "RETURN",
|
||||
"gas" : 290454,
|
||||
"gasCost" : 0,
|
||||
"depth" : 1,
|
||||
"stack" : [ "0x9dc2c8f5", "0x0", "0x0" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,21 +5,21 @@
|
||||
"method": "eth_call",
|
||||
"params": [
|
||||
{
|
||||
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
|
||||
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"data": "0x12a7b914"
|
||||
"comment": "Call to ECREC Precompiled on a different address, expect the original behaviour of ECREC precompile",
|
||||
"from": "0xc100000000000000000000000000000000000000",
|
||||
"to": "0x0000000000000000000000000000000000123456",
|
||||
"input": "0x82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd"
|
||||
},
|
||||
"latest",
|
||||
{
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"0xc100000000000000000000000000000000000000": {
|
||||
"balance": "0xde0b6b3a7640000",
|
||||
"nonce": 88
|
||||
},
|
||||
"0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": {
|
||||
"stateDiff": {
|
||||
"0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7"
|
||||
},
|
||||
"movePrecompileToAddress":null
|
||||
"0x0000000000000000000000000000000000000001": {
|
||||
"comment": "Move ECREC Precompiled to address",
|
||||
"code": "0x60003560010160005260206000f3",
|
||||
"movePrecompileToAddress": "0x0000000000000000000000000000000000123456"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -27,7 +27,8 @@
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 3,
|
||||
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
"comment": "The original ECREC precompile behaviour is expected, not the overridden one",
|
||||
"result": "0x000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"request": {
|
||||
"id": 3,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_call",
|
||||
"params": [
|
||||
{
|
||||
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
|
||||
"from": "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"data": "0x12a7b914"
|
||||
},
|
||||
"latest",
|
||||
{
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0xde0b6b3a7640000",
|
||||
"nonce": 88
|
||||
},
|
||||
"0xb9741079a300Cb3B8f324CdDB847c0d1d273a05E": {
|
||||
"stateDiff": {
|
||||
"0x1cf7945003fc5b59d2f6736f0704557aa805c4f2844084ccd1173b8d56946962": "0x000000000000000000000000000000000000000000000000000000110ed03bf7"
|
||||
},
|
||||
"movePrecompileToAddress":null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 3,
|
||||
"result": "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"request": {
|
||||
"id": 3,
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_call",
|
||||
"params": [
|
||||
{
|
||||
"from": "0xc100000000000000000000000000000000000000",
|
||||
"comment": "Call to precompile ECREC (0x01), but code was modified to add 1 to input",
|
||||
"to": "0x0000000000000000000000000000000000000001",
|
||||
"input": "0x0000000000000000000000000000000000000000000000000000000000000001"
|
||||
},
|
||||
"latest",
|
||||
{
|
||||
"0xc100000000000000000000000000000000000000": {
|
||||
"balance": "0xde0b6b3a7640000"
|
||||
},
|
||||
"0x0000000000000000000000000000000000000001": {
|
||||
"comment": "The code below adds one to input",
|
||||
"code": "0x60003560010160005260206000f3",
|
||||
"movePrecompileToAddress": "0x0000000000000000000000000000000000123456"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 3,
|
||||
"result": "0x0000000000000000000000000000000000000000000000000000000000000002"
|
||||
},
|
||||
"statusCode": 200
|
||||
}
|
||||
@@ -153,7 +153,6 @@ public class TraceTransactionIntegrationTest {
|
||||
// No storage changes before the SSTORE call.
|
||||
TraceFrame frame = tracer.getTraceFrames().get(170);
|
||||
assertThat(frame.getOpcode()).isEqualTo("DUP6");
|
||||
assertStorageContainsExactly(frame);
|
||||
|
||||
// Storage changes show up in the SSTORE frame.
|
||||
frame = tracer.getTraceFrames().get(171);
|
||||
@@ -201,8 +200,6 @@ public class TraceTransactionIntegrationTest {
|
||||
assertThat(frame.getOpcode()).isEqualTo("PUSH1");
|
||||
assertThat(frame.getPc()).isEqualTo(0);
|
||||
assertStackContainsExactly(frame);
|
||||
assertMemoryContainsExactly(frame);
|
||||
assertStorageContainsExactly(frame);
|
||||
|
||||
frame = traceFrames.get(1);
|
||||
assertThat(frame.getDepth()).isEqualTo(expectedDepth);
|
||||
@@ -211,8 +208,6 @@ public class TraceTransactionIntegrationTest {
|
||||
assertThat(frame.getOpcode()).isEqualTo("PUSH1");
|
||||
assertThat(frame.getPc()).isEqualTo(2);
|
||||
assertStackContainsExactly(frame, "0x80");
|
||||
assertMemoryContainsExactly(frame);
|
||||
assertStorageContainsExactly(frame);
|
||||
|
||||
frame = traceFrames.get(2);
|
||||
assertThat(frame.getDepth()).isEqualTo(expectedDepth);
|
||||
@@ -226,7 +221,6 @@ public class TraceTransactionIntegrationTest {
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000080");
|
||||
assertStorageContainsExactly(frame);
|
||||
// Reference implementation actually records the memory after expansion but before the store.
|
||||
// assertMemoryContainsExactly(frame,
|
||||
// "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
@@ -245,7 +239,6 @@ public class TraceTransactionIntegrationTest {
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000080");
|
||||
assertStorageContainsExactly(frame);
|
||||
}
|
||||
|
||||
private void assertStackContainsExactly(
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.core.encoding.CodeDelegationTransactionEncoder;
|
||||
import org.hyperledger.besu.ethereum.core.json.ChainIdDeserializer;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -28,10 +29,14 @@ import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
// ignore `signer` field used in execution-spec-tests
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelegation {
|
||||
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
|
||||
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
|
||||
@@ -77,14 +82,23 @@ public class CodeDelegation implements org.hyperledger.besu.datatypes.CodeDelega
|
||||
*/
|
||||
@JsonCreator
|
||||
public static org.hyperledger.besu.datatypes.CodeDelegation createCodeDelegation(
|
||||
@JsonProperty("chainId") final BigInteger chainId,
|
||||
@JsonProperty("chainId") @JsonDeserialize(using = ChainIdDeserializer.class)
|
||||
final BigInteger chainId,
|
||||
@JsonProperty("address") final Address address,
|
||||
@JsonProperty("nonce") final long nonce,
|
||||
@JsonProperty("v") final byte v,
|
||||
@JsonProperty("r") final BigInteger r,
|
||||
@JsonProperty("s") final BigInteger s) {
|
||||
@JsonProperty("nonce") final String nonce,
|
||||
@JsonProperty("v") final String v,
|
||||
@JsonProperty("r") final String r,
|
||||
@JsonProperty("s") final String s) {
|
||||
return new CodeDelegation(
|
||||
chainId, address, nonce, SIGNATURE_ALGORITHM.get().createSignature(r, s, v));
|
||||
chainId,
|
||||
address,
|
||||
Bytes.fromHexStringLenient(nonce).toLong(),
|
||||
SIGNATURE_ALGORITHM
|
||||
.get()
|
||||
.createSignature(
|
||||
Bytes.fromHexStringLenient(r).toUnsignedBigInteger(),
|
||||
Bytes.fromHexStringLenient(s).toUnsignedBigInteger(),
|
||||
Bytes.fromHexStringLenient(v).get(0)));
|
||||
}
|
||||
|
||||
@JsonProperty("chainId")
|
||||
|
||||
@@ -29,4 +29,13 @@ public record Request(RequestType type, Bytes data)
|
||||
public Bytes getData() {
|
||||
return data();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serialized form of the concatenated type and data.
|
||||
*
|
||||
* @return the serialized request as a byte.
|
||||
*/
|
||||
public Bytes getEncodedRequest() {
|
||||
return Bytes.concatenate(Bytes.of(getType().ordinal()), getData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ public class ChainIdDeserializer extends StdDeserializer<BigInteger> {
|
||||
final var chainId =
|
||||
UInt256.fromHexString(jsonparser.getCodec().readValue(jsonparser, String.class))
|
||||
.toBigInteger();
|
||||
if (chainId.signum() <= 0) {
|
||||
throw new IllegalArgumentException("Non positive chain id: " + chainId);
|
||||
if (chainId.signum() < 0) {
|
||||
throw new IllegalArgumentException("Negative chain id: " + chainId);
|
||||
}
|
||||
return chainId;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class TraceOptions {
|
||||
private final boolean traceMemory;
|
||||
private final boolean traceStack;
|
||||
|
||||
public static final TraceOptions DEFAULT = new TraceOptions(true, true, true);
|
||||
public static final TraceOptions DEFAULT = new TraceOptions(true, false, true);
|
||||
|
||||
public TraceOptions(
|
||||
final boolean traceStorage, final boolean traceMemory, final boolean traceStack) {
|
||||
|
||||
@@ -92,20 +92,18 @@ public final class BodyValidation {
|
||||
/**
|
||||
* Generates the requests hash for a list of requests
|
||||
*
|
||||
* @param requests list of request
|
||||
* @param requests list of request (must be sorted by request type ascending)
|
||||
* @return the requests hash
|
||||
*/
|
||||
public static Hash requestsHash(final List<Request> requests) {
|
||||
List<Bytes> requestHashes = new ArrayList<>();
|
||||
IntStream.range(0, requests.size())
|
||||
.forEach(
|
||||
i -> {
|
||||
final Request request = requests.get(i);
|
||||
final Bytes requestBytes =
|
||||
Bytes.concatenate(
|
||||
Bytes.of(request.getType().getSerializedType()), request.getData());
|
||||
requestHashes.add(sha256(requestBytes));
|
||||
});
|
||||
requests.forEach(
|
||||
request -> {
|
||||
// empty requests are excluded from the hash
|
||||
if (!request.getData().isEmpty()) {
|
||||
requestHashes.add(sha256(request.getEncodedRequest()));
|
||||
}
|
||||
});
|
||||
|
||||
return Hash.wrap(sha256(Bytes.wrap(requestHashes)));
|
||||
}
|
||||
|
||||
@@ -175,16 +175,17 @@ public class ClassicProtocolSpecs {
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(false)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
|
||||
.build())
|
||||
.name("Atlantis");
|
||||
}
|
||||
|
||||
@@ -357,16 +358,17 @@ public class ClassicProtocolSpecs {
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(true)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
|
||||
.build())
|
||||
.name("Spiral");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,16 +136,17 @@ public abstract class MainnetProtocolSpecs {
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
false,
|
||||
false,
|
||||
evmConfiguration.evmStackSize(),
|
||||
FeeMarket.legacy(),
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(false)
|
||||
.warmCoinbase(false)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(FeeMarket.legacy())
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
|
||||
.build())
|
||||
.privateTransactionProcessorBuilder(
|
||||
(transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
@@ -297,16 +298,17 @@ public abstract class MainnetProtocolSpecs {
|
||||
transactionValidator,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidator,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.frontier()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidator)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(false)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
|
||||
.build())
|
||||
.name("SpuriousDragon");
|
||||
}
|
||||
|
||||
@@ -503,16 +505,17 @@ public abstract class MainnetProtocolSpecs {
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
false,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(false)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.eip1559())
|
||||
.build())
|
||||
.contractCreationProcessorBuilder(
|
||||
evm ->
|
||||
new ContractCreationProcessor(
|
||||
@@ -635,16 +638,17 @@ public abstract class MainnetProtocolSpecs {
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559()))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(true)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.eip1559())
|
||||
.build())
|
||||
// Contract creation rules for EIP-3860 Limit and meter intitcode
|
||||
.transactionValidatorFactoryBuilder(
|
||||
(evm, gasLimitCalculator, feeMarket) ->
|
||||
@@ -722,18 +726,20 @@ public abstract class MainnetProtocolSpecs {
|
||||
transactionValidator,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor) ->
|
||||
new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidator,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
true,
|
||||
true,
|
||||
evmConfiguration.evmStackSize(),
|
||||
feeMarket,
|
||||
CoinbaseFeePriceCalculator.eip1559(),
|
||||
new CodeDelegationProcessor(
|
||||
chainId, SIGNATURE_ALGORITHM.get().getHalfCurveOrder())))
|
||||
MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidator)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(true)
|
||||
.warmCoinbase(true)
|
||||
.maxStackSize(evmConfiguration.evmStackSize())
|
||||
.feeMarket(feeMarket)
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.eip1559())
|
||||
.codeDelegationProcessor(
|
||||
new CodeDelegationProcessor(
|
||||
chainId, SIGNATURE_ALGORITHM.get().getHalfCurveOrder()))
|
||||
.build())
|
||||
// change to check for max blob gas per block for EIP-4844
|
||||
.transactionValidatorFactoryBuilder(
|
||||
(evm, gasLimitCalculator, feeMarket) ->
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.processor.AbstractMessageProcessor;
|
||||
import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
|
||||
import org.hyperledger.besu.evm.processor.MessageCallProcessor;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.EVMWorldUpdater;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
@@ -68,9 +70,9 @@ public class MainnetTransactionProcessor {
|
||||
|
||||
protected final TransactionValidatorFactory transactionValidatorFactory;
|
||||
|
||||
private final AbstractMessageProcessor contractCreationProcessor;
|
||||
private final ContractCreationProcessor contractCreationProcessor;
|
||||
|
||||
private final AbstractMessageProcessor messageCallProcessor;
|
||||
private final MessageCallProcessor messageCallProcessor;
|
||||
|
||||
private final int maxStackSize;
|
||||
|
||||
@@ -83,34 +85,11 @@ public class MainnetTransactionProcessor {
|
||||
|
||||
private final Optional<CodeDelegationProcessor> maybeCodeDelegationProcessor;
|
||||
|
||||
public MainnetTransactionProcessor(
|
||||
private MainnetTransactionProcessor(
|
||||
final GasCalculator gasCalculator,
|
||||
final TransactionValidatorFactory transactionValidatorFactory,
|
||||
final AbstractMessageProcessor contractCreationProcessor,
|
||||
final AbstractMessageProcessor messageCallProcessor,
|
||||
final boolean clearEmptyAccounts,
|
||||
final boolean warmCoinbase,
|
||||
final int maxStackSize,
|
||||
final FeeMarket feeMarket,
|
||||
final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) {
|
||||
this(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
clearEmptyAccounts,
|
||||
warmCoinbase,
|
||||
maxStackSize,
|
||||
feeMarket,
|
||||
coinbaseFeePriceCalculator,
|
||||
null);
|
||||
}
|
||||
|
||||
public MainnetTransactionProcessor(
|
||||
final GasCalculator gasCalculator,
|
||||
final TransactionValidatorFactory transactionValidatorFactory,
|
||||
final AbstractMessageProcessor contractCreationProcessor,
|
||||
final AbstractMessageProcessor messageCallProcessor,
|
||||
final ContractCreationProcessor contractCreationProcessor,
|
||||
final MessageCallProcessor messageCallProcessor,
|
||||
final boolean clearEmptyAccounts,
|
||||
final boolean warmCoinbase,
|
||||
final int maxStackSize,
|
||||
@@ -500,11 +479,8 @@ public class MainnetTransactionProcessor {
|
||||
|
||||
// Refund the sender by what we should and pay the miner fee (note that we're doing them one
|
||||
// after the other so that if it is the same account somehow, we end up with the right result)
|
||||
final long selfDestructRefund =
|
||||
gasCalculator.getSelfDestructRefundAmount() * initialFrame.getSelfDestructs().size();
|
||||
final long baseRefundGas =
|
||||
initialFrame.getGasRefund() + selfDestructRefund + codeDelegationRefund;
|
||||
final long refundedGas = refunded(transaction, initialFrame.getRemainingGas(), baseRefundGas);
|
||||
final long refundedGas =
|
||||
gasCalculator.calculateGasRefund(transaction, initialFrame, codeDelegationRefund);
|
||||
final Wei refundedWei = transactionGasPrice.multiply(refundedGas);
|
||||
final Wei balancePriorToRefund = sender.getBalance();
|
||||
sender.incrementBalance(refundedWei);
|
||||
@@ -635,13 +611,8 @@ public class MainnetTransactionProcessor {
|
||||
};
|
||||
}
|
||||
|
||||
protected long refunded(
|
||||
final Transaction transaction, final long gasRemaining, final long gasRefund) {
|
||||
// Integer truncation takes care of the floor calculation needed after the divide.
|
||||
final long maxRefundAllowance =
|
||||
(transaction.getGasLimit() - gasRemaining) / gasCalculator.getMaxRefundQuotient();
|
||||
final long refundAllowance = Math.min(maxRefundAllowance, gasRefund);
|
||||
return gasRemaining + refundAllowance;
|
||||
public MessageCallProcessor getMessageCallProcessor() {
|
||||
return messageCallProcessor;
|
||||
}
|
||||
|
||||
private String printableStackTraceFromThrowable(final RuntimeException re) {
|
||||
@@ -653,4 +624,103 @@ public class MainnetTransactionProcessor {
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private GasCalculator gasCalculator;
|
||||
private TransactionValidatorFactory transactionValidatorFactory;
|
||||
private ContractCreationProcessor contractCreationProcessor;
|
||||
private MessageCallProcessor messageCallProcessor;
|
||||
private boolean clearEmptyAccounts;
|
||||
private boolean warmCoinbase;
|
||||
private int maxStackSize;
|
||||
private FeeMarket feeMarket;
|
||||
private CoinbaseFeePriceCalculator coinbaseFeePriceCalculator;
|
||||
private CodeDelegationProcessor codeDelegationProcessor;
|
||||
|
||||
public Builder gasCalculator(final GasCalculator gasCalculator) {
|
||||
this.gasCalculator = gasCalculator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder transactionValidatorFactory(
|
||||
final TransactionValidatorFactory transactionValidatorFactory) {
|
||||
this.transactionValidatorFactory = transactionValidatorFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder contractCreationProcessor(
|
||||
final ContractCreationProcessor contractCreationProcessor) {
|
||||
this.contractCreationProcessor = contractCreationProcessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder messageCallProcessor(final MessageCallProcessor messageCallProcessor) {
|
||||
this.messageCallProcessor = messageCallProcessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder clearEmptyAccounts(final boolean clearEmptyAccounts) {
|
||||
this.clearEmptyAccounts = clearEmptyAccounts;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder warmCoinbase(final boolean warmCoinbase) {
|
||||
this.warmCoinbase = warmCoinbase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder maxStackSize(final int maxStackSize) {
|
||||
this.maxStackSize = maxStackSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder feeMarket(final FeeMarket feeMarket) {
|
||||
this.feeMarket = feeMarket;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder coinbaseFeePriceCalculator(
|
||||
final CoinbaseFeePriceCalculator coinbaseFeePriceCalculator) {
|
||||
this.coinbaseFeePriceCalculator = coinbaseFeePriceCalculator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder codeDelegationProcessor(
|
||||
final CodeDelegationProcessor maybeCodeDelegationProcessor) {
|
||||
this.codeDelegationProcessor = maybeCodeDelegationProcessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder populateFrom(final MainnetTransactionProcessor processor) {
|
||||
this.gasCalculator = processor.gasCalculator;
|
||||
this.transactionValidatorFactory = processor.transactionValidatorFactory;
|
||||
this.contractCreationProcessor = processor.contractCreationProcessor;
|
||||
this.messageCallProcessor = processor.messageCallProcessor;
|
||||
this.clearEmptyAccounts = processor.clearEmptyAccounts;
|
||||
this.warmCoinbase = processor.warmCoinbase;
|
||||
this.maxStackSize = processor.maxStackSize;
|
||||
this.feeMarket = processor.feeMarket;
|
||||
this.coinbaseFeePriceCalculator = processor.coinbaseFeePriceCalculator;
|
||||
this.codeDelegationProcessor = processor.maybeCodeDelegationProcessor.orElse(null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MainnetTransactionProcessor build() {
|
||||
return new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
clearEmptyAccounts,
|
||||
warmCoinbase,
|
||||
maxStackSize,
|
||||
feeMarket,
|
||||
coinbaseFeePriceCalculator,
|
||||
codeDelegationProcessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;
|
||||
import org.hyperledger.besu.evm.processor.AbstractMessageProcessor;
|
||||
import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
|
||||
import org.hyperledger.besu.evm.processor.MessageCallProcessor;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -62,10 +64,10 @@ public class ProtocolSpecBuilder {
|
||||
private Function<FeeMarket, BlockHeaderValidator.Builder> blockHeaderValidatorBuilder;
|
||||
private Function<FeeMarket, BlockHeaderValidator.Builder> ommerHeaderValidatorBuilder;
|
||||
private Function<ProtocolSchedule, BlockBodyValidator> blockBodyValidatorBuilder;
|
||||
private Function<EVM, AbstractMessageProcessor> contractCreationProcessorBuilder;
|
||||
private Function<EVM, ContractCreationProcessor> contractCreationProcessorBuilder;
|
||||
private Function<PrecompiledContractConfiguration, PrecompileContractRegistry>
|
||||
precompileContractRegistryBuilder;
|
||||
private BiFunction<EVM, PrecompileContractRegistry, AbstractMessageProcessor>
|
||||
private BiFunction<EVM, PrecompileContractRegistry, MessageCallProcessor>
|
||||
messageCallProcessorBuilder;
|
||||
private TransactionProcessorBuilder transactionProcessorBuilder;
|
||||
|
||||
@@ -158,7 +160,7 @@ public class ProtocolSpecBuilder {
|
||||
}
|
||||
|
||||
public ProtocolSpecBuilder contractCreationProcessorBuilder(
|
||||
final Function<EVM, AbstractMessageProcessor> contractCreationProcessorBuilder) {
|
||||
final Function<EVM, ContractCreationProcessor> contractCreationProcessorBuilder) {
|
||||
this.contractCreationProcessorBuilder = contractCreationProcessorBuilder;
|
||||
return this;
|
||||
}
|
||||
@@ -180,7 +182,7 @@ public class ProtocolSpecBuilder {
|
||||
}
|
||||
|
||||
public ProtocolSpecBuilder messageCallProcessorBuilder(
|
||||
final BiFunction<EVM, PrecompileContractRegistry, AbstractMessageProcessor>
|
||||
final BiFunction<EVM, PrecompileContractRegistry, MessageCallProcessor>
|
||||
messageCallProcessorBuilder) {
|
||||
this.messageCallProcessorBuilder = messageCallProcessorBuilder;
|
||||
return this;
|
||||
@@ -330,11 +332,11 @@ public class ProtocolSpecBuilder {
|
||||
new PrecompiledContractConfiguration(gasCalculator, privacyParameters);
|
||||
final TransactionValidatorFactory transactionValidatorFactory =
|
||||
transactionValidatorFactoryBuilder.apply(evm, gasLimitCalculator, feeMarket);
|
||||
final AbstractMessageProcessor contractCreationProcessor =
|
||||
final ContractCreationProcessor contractCreationProcessor =
|
||||
contractCreationProcessorBuilder.apply(evm);
|
||||
final PrecompileContractRegistry precompileContractRegistry =
|
||||
precompileContractRegistryBuilder.apply(precompiledContractConfiguration);
|
||||
final AbstractMessageProcessor messageCallProcessor =
|
||||
final MessageCallProcessor messageCallProcessor =
|
||||
messageCallProcessorBuilder.apply(evm, precompileContractRegistry);
|
||||
final MainnetTransactionProcessor transactionProcessor =
|
||||
transactionProcessorBuilder.apply(
|
||||
@@ -469,8 +471,8 @@ public class ProtocolSpecBuilder {
|
||||
GasCalculator gasCalculator,
|
||||
FeeMarket feeMarket,
|
||||
TransactionValidatorFactory transactionValidatorFactory,
|
||||
AbstractMessageProcessor contractCreationProcessor,
|
||||
AbstractMessageProcessor messageCallProcessor);
|
||||
ContractCreationProcessor contractCreationProcessor,
|
||||
MessageCallProcessor messageCallProcessor);
|
||||
}
|
||||
|
||||
public interface PrivateTransactionProcessorBuilder {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright contributors to 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.transaction;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.StateOverrideMap;
|
||||
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.evm.processor.OverriddenPrecompilesMessageCallProcessor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SimulationTransactionProcessorFactory {
|
||||
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
|
||||
/**
|
||||
* Creates a factory capable of producing transaction processors.
|
||||
*
|
||||
* @param protocolSchedule the protocol schedule used for creating processors
|
||||
*/
|
||||
public SimulationTransactionProcessorFactory(final ProtocolSchedule protocolSchedule) {
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transaction processor, optionally applying state overrides.
|
||||
*
|
||||
* @param processableHeader the block header to process transactions against
|
||||
* @param maybeStateOverrides optional state overrides for simulation
|
||||
* @return a transaction processor, with overrides applied if provided
|
||||
*/
|
||||
public MainnetTransactionProcessor getTransactionProcessor(
|
||||
final ProcessableBlockHeader processableHeader,
|
||||
final Optional<StateOverrideMap> maybeStateOverrides) {
|
||||
|
||||
MainnetTransactionProcessor baseProcessor =
|
||||
protocolSchedule.getByBlockHeader(processableHeader).getTransactionProcessor();
|
||||
|
||||
return maybeStateOverrides
|
||||
.flatMap(this::extractPrecompileAddressOverrides)
|
||||
.map(
|
||||
precompileOverrides -> createProcessorWithOverrides(baseProcessor, precompileOverrides))
|
||||
.orElse(baseProcessor);
|
||||
}
|
||||
|
||||
private Optional<Map<Address, Address>> extractPrecompileAddressOverrides(
|
||||
final StateOverrideMap stateOverrides) {
|
||||
Map<Address, Address> addressOverrides =
|
||||
stateOverrides.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().getMovePrecompileToAddress().isPresent())
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
entry -> entry.getValue().getMovePrecompileToAddress().get()));
|
||||
|
||||
return addressOverrides.isEmpty() ? Optional.empty() : Optional.of(addressOverrides);
|
||||
}
|
||||
|
||||
private MainnetTransactionProcessor createProcessorWithOverrides(
|
||||
final MainnetTransactionProcessor baseProcessor,
|
||||
final Map<Address, Address> precompileAddressOverrides) {
|
||||
return MainnetTransactionProcessor.builder()
|
||||
.populateFrom(baseProcessor)
|
||||
.messageCallProcessor(
|
||||
new OverriddenPrecompilesMessageCallProcessor(
|
||||
baseProcessor.getMessageCallProcessor(), precompileAddressOverrides))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,7 @@ public class TransactionSimulator {
|
||||
private final WorldStateArchive worldStateArchive;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningConfiguration miningConfiguration;
|
||||
private final SimulationTransactionProcessorFactory simulationTransactionProcessorFactory;
|
||||
private final long rpcGasCap;
|
||||
|
||||
public TransactionSimulator(
|
||||
@@ -100,6 +101,8 @@ public class TransactionSimulator {
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningConfiguration = miningConfiguration;
|
||||
this.rpcGasCap = rpcGasCap;
|
||||
this.simulationTransactionProcessorFactory =
|
||||
new SimulationTransactionProcessorFactory(protocolSchedule);
|
||||
}
|
||||
|
||||
public Optional<TransactionSimulatorResult> process(
|
||||
@@ -402,8 +405,9 @@ public class TransactionSimulator {
|
||||
final long simulationGasCap =
|
||||
calculateSimulationGasCap(callParams.getGasLimit(), blockHeaderToProcess.getGasLimit());
|
||||
|
||||
final MainnetTransactionProcessor transactionProcessor =
|
||||
protocolSchedule.getByBlockHeader(blockHeaderToProcess).getTransactionProcessor();
|
||||
MainnetTransactionProcessor transactionProcessor =
|
||||
simulationTransactionProcessorFactory.getTransactionProcessor(
|
||||
processableHeader, maybeStateOverrides);
|
||||
|
||||
final Optional<BlockHeader> maybeParentHeader =
|
||||
blockchain.getBlockHeader(blockHeaderToProcess.getParentHash());
|
||||
|
||||
@@ -218,9 +218,10 @@ public class DebugOperationTracer implements OperationTracer {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
final Map<UInt256, UInt256> storageContents =
|
||||
new TreeMap<>(
|
||||
frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getUpdatedStorage());
|
||||
Map<UInt256, UInt256> updatedStorage =
|
||||
frame.getWorldUpdater().getAccount(frame.getRecipientAddress()).getUpdatedStorage();
|
||||
if (updatedStorage.isEmpty()) return Optional.empty();
|
||||
final Map<UInt256, UInt256> storageContents = new TreeMap<>(updatedStorage);
|
||||
|
||||
return Optional.of(storageContents);
|
||||
} catch (final ModificationNotAllowedException e) {
|
||||
@@ -229,7 +230,7 @@ public class DebugOperationTracer implements OperationTracer {
|
||||
}
|
||||
|
||||
private Optional<Bytes[]> captureMemory(final MessageFrame frame) {
|
||||
if (!options.isMemoryEnabled()) {
|
||||
if (!options.isMemoryEnabled() || frame.memoryWordSize() == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final Bytes[] memoryContents = new Bytes[frame.memoryWordSize()];
|
||||
|
||||
@@ -290,7 +290,7 @@ final class GenesisStateTest {
|
||||
assertThat(header.getHash())
|
||||
.isEqualTo(
|
||||
Hash.fromHexString(
|
||||
"0x554807b22674e6d335f734485993857bbad7a9543affb0663a10c14d78135ec7"));
|
||||
"0x5d2d02fce02d1b7ca635ec91a4fe6f7aa36f9b3997ec4304e8c68d8f6f15d266"));
|
||||
assertThat(header.getGasLimit()).isEqualTo(0x2fefd8);
|
||||
assertThat(header.getGasUsed()).isZero();
|
||||
assertThat(header.getNumber()).isZero();
|
||||
@@ -330,7 +330,7 @@ final class GenesisStateTest {
|
||||
assertThat(header.getRequestsHash().get())
|
||||
.isEqualTo(
|
||||
Hash.fromHexString(
|
||||
"0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f"));
|
||||
"0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -34,7 +34,8 @@ import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
import org.hyperledger.besu.evm.processor.AbstractMessageProcessor;
|
||||
import org.hyperledger.besu.evm.processor.ContractCreationProcessor;
|
||||
import org.hyperledger.besu.evm.processor.MessageCallProcessor;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldView;
|
||||
@@ -67,8 +68,8 @@ class MainnetTransactionProcessorTest {
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private TransactionValidatorFactory transactionValidatorFactory;
|
||||
|
||||
@Mock private AbstractMessageProcessor contractCreationProcessor;
|
||||
@Mock private AbstractMessageProcessor messageCallProcessor;
|
||||
@Mock private ContractCreationProcessor contractCreationProcessor;
|
||||
@Mock private MessageCallProcessor messageCallProcessor;
|
||||
|
||||
@Mock private WorldUpdater worldState;
|
||||
@Mock private ProcessableBlockHeader blockHeader;
|
||||
@@ -79,17 +80,19 @@ class MainnetTransactionProcessorTest {
|
||||
@Mock private MutableAccount receiverAccount;
|
||||
|
||||
MainnetTransactionProcessor createTransactionProcessor(final boolean warmCoinbase) {
|
||||
return new MainnetTransactionProcessor(
|
||||
gasCalculator,
|
||||
transactionValidatorFactory,
|
||||
contractCreationProcessor,
|
||||
messageCallProcessor,
|
||||
false,
|
||||
warmCoinbase,
|
||||
MAX_STACK_SIZE,
|
||||
FeeMarket.legacy(),
|
||||
CoinbaseFeePriceCalculator.frontier(),
|
||||
new CodeDelegationProcessor(Optional.of(BigInteger.ONE), BigInteger.TEN));
|
||||
return MainnetTransactionProcessor.builder()
|
||||
.gasCalculator(gasCalculator)
|
||||
.transactionValidatorFactory(transactionValidatorFactory)
|
||||
.contractCreationProcessor(contractCreationProcessor)
|
||||
.messageCallProcessor(messageCallProcessor)
|
||||
.clearEmptyAccounts(false)
|
||||
.warmCoinbase(warmCoinbase)
|
||||
.maxStackSize(MAX_STACK_SIZE)
|
||||
.feeMarket(FeeMarket.legacy())
|
||||
.coinbaseFeePriceCalculator(CoinbaseFeePriceCalculator.frontier())
|
||||
.codeDelegationProcessor(
|
||||
new CodeDelegationProcessor(Optional.of(BigInteger.ONE), BigInteger.TEN))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright contributors to 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.transaction;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.StateOverride;
|
||||
import org.hyperledger.besu.datatypes.StateOverrideMap;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.evm.EVM;
|
||||
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;
|
||||
import org.hyperledger.besu.evm.precompile.PrecompiledContract;
|
||||
import org.hyperledger.besu.evm.processor.MessageCallProcessor;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class SimulationTransactionProcessorFactoryTest {
|
||||
|
||||
private SimulationTransactionProcessorFactory factory;
|
||||
private final Address originalPrecompileAddress = Address.fromHexString("0x1");
|
||||
private final Address newPrecompileAddress = Address.fromHexString("0x2");
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ProtocolSpec protocolSpec = mock(ProtocolSpec.class);
|
||||
ProtocolSchedule protocolSchedule = mock(ProtocolSchedule.class);
|
||||
when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec);
|
||||
|
||||
PrecompileContractRegistry precompileContractRegistry = new PrecompileContractRegistry();
|
||||
precompileContractRegistry.put(originalPrecompileAddress, mock(PrecompiledContract.class));
|
||||
|
||||
MainnetTransactionProcessor mainnetTransactionProcessor =
|
||||
MainnetTransactionProcessor.builder()
|
||||
.messageCallProcessor(
|
||||
new MessageCallProcessor(mock(EVM.class), precompileContractRegistry))
|
||||
.build();
|
||||
when(protocolSpec.getTransactionProcessor()).thenReturn(mainnetTransactionProcessor);
|
||||
|
||||
factory = new SimulationTransactionProcessorFactory(protocolSchedule);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnProcessorWithOriginalPrecompileAddressesIfNoOverrides() {
|
||||
MainnetTransactionProcessor simulationTransactionProcessor =
|
||||
factory.getTransactionProcessor(null, Optional.empty());
|
||||
Set<Address> precompileAddresses =
|
||||
simulationTransactionProcessor.getMessageCallProcessor().getPrecompileAddresses();
|
||||
|
||||
assertThat(precompileAddresses).containsExactlyInAnyOrder(originalPrecompileAddress);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnProcessorWithNewPrecompileAddressesWithOverrides() {
|
||||
StateOverrideMap stateOverrideMap = new StateOverrideMap();
|
||||
stateOverrideMap.put(
|
||||
originalPrecompileAddress,
|
||||
new StateOverride.Builder().withMovePrecompileToAddress(newPrecompileAddress).build());
|
||||
|
||||
MainnetTransactionProcessor simulationTransactionProcessor =
|
||||
factory.getTransactionProcessor(null, Optional.of(stateOverrideMap));
|
||||
Set<Address> precompileAddresses =
|
||||
simulationTransactionProcessor.getMessageCallProcessor().getPrecompileAddresses();
|
||||
|
||||
assertThat(precompileAddresses).containsExactlyInAnyOrder(newPrecompileAddress);
|
||||
}
|
||||
}
|
||||
@@ -546,7 +546,12 @@ public class T8nExecutor {
|
||||
ArrayNode requests = resultObject.putArray("requests");
|
||||
maybeRequests
|
||||
.orElseGet(List::of)
|
||||
.forEach(request -> requests.add(request.getData().toHexString()));
|
||||
.forEach(
|
||||
request -> {
|
||||
if (!request.data().isEmpty()) {
|
||||
requests.add(request.getEncodedRequest().toHexString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
worldState.persist(blockHeader);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Configuration level="WARN">
|
||||
<Properties>
|
||||
<Property name="root.log.level">INFO</Property>
|
||||
</Properties>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -189,14 +189,6 @@
|
||||
"balance": "0x0",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0x0f792be4b0c0cb4dae440ef133e90c0ecd48cccc":{
|
||||
"code":"0x3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500",
|
||||
"storage":{
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000":"0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb"
|
||||
},
|
||||
"balance":"0x0",
|
||||
"nonce":"0x1"
|
||||
},
|
||||
"0x0c15f14308530b7cdb8460094bbb9cc28b9aaaaa": {
|
||||
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd",
|
||||
"storage": {
|
||||
@@ -206,6 +198,14 @@
|
||||
"balance": "0x1",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0x0f792be4b0c0cb4dae440ef133e90c0ecd48cccc": {
|
||||
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500",
|
||||
"storage": {
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x10715cfbefdb8a0cb2f7d7ca5ee6d1ea65515ecb41cff0a22d1e11716a9d27fb"
|
||||
},
|
||||
"balance": "0x0",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0xad78ebc5ac61f2b034",
|
||||
"nonce": "0x1"
|
||||
@@ -213,11 +213,9 @@
|
||||
},
|
||||
"body": "0xf89bf8998007830f424094000000000000000000000000000000000000100080b838000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000026a0d050db98a60dbe4bbbc6ce154c607f28f1cf803a8882f369b28a5eb4ef1a600fa07512ca5133bcb887a41f6136cd645839c1bcf0f300325948387a70f3ad9ced1c",
|
||||
"result": {
|
||||
"requestsHash": "0xab205d558af6253557180e19e89356ed4c7d4b13615ee9560840af3df75ddb12",
|
||||
"requestsHash": "0x16a372318fd60f169dd3e1e2e528d1fb17edc62e741feebcb0896f950018769a",
|
||||
"requests": [
|
||||
"0x",
|
||||
"0x00000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000",
|
||||
"0x"
|
||||
"0x0100000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000"
|
||||
],
|
||||
"stateRoot": "0xc7b49e4aef4229962b94ec0a7c83a6fc0b4015f2573b9a85446ed434c823164e",
|
||||
"txRoot": "0x0d36638e52999b7beafa00eb94f7ca23139774cd14229c011d0edc1fc66125c9",
|
||||
|
||||
@@ -29,12 +29,15 @@ import java.util.Optional;
|
||||
|
||||
import com.google.common.net.InetAddresses;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Encapsulates the network coordinates of a {@link DiscoveryPeer} as well as serialization logic
|
||||
* used in various Discovery messages.
|
||||
*/
|
||||
public class Endpoint {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Endpoint.class);
|
||||
private final Optional<String> host;
|
||||
private final int udpPort;
|
||||
private final Optional<Integer> tcpPort;
|
||||
@@ -49,15 +52,16 @@ public class Endpoint {
|
||||
}
|
||||
|
||||
public static Endpoint fromEnode(final EnodeURL enode) {
|
||||
final int discoveryPort =
|
||||
enode
|
||||
.getDiscoveryPort()
|
||||
.orElseThrow(
|
||||
() ->
|
||||
new IllegalArgumentException(
|
||||
"Attempt to create a discovery endpoint for an enode with discovery disabled."));
|
||||
Optional<Integer> discoveryPort = enode.getDiscoveryPort();
|
||||
|
||||
if (discoveryPort.isEmpty()) {
|
||||
int defaultPort = EnodeURLImpl.DEFAULT_LISTENING_PORT;
|
||||
LOG.debug("Discovery disabled for enode {}. Using default port {}.", enode, defaultPort);
|
||||
return new Endpoint(enode.getIp().getHostAddress(), defaultPort, Optional.empty());
|
||||
}
|
||||
|
||||
final Optional<Integer> listeningPort = enode.getListeningPort();
|
||||
return new Endpoint(enode.getIp().getHostAddress(), discoveryPort, listeningPort);
|
||||
return new Endpoint(enode.getIp().getHostAddress(), discoveryPort.get(), listeningPort);
|
||||
}
|
||||
|
||||
public EnodeURL toEnode(final Bytes nodeId) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -45,6 +46,8 @@ import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissions.Action;
|
||||
import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissionsDenylist;
|
||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -898,6 +901,23 @@ public class PeerDiscoveryAgentTest {
|
||||
assertThat(PeerDiscoveryAgent.deriveHost(source, mockWellFormed)).isEqualTo(routableHost);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFromEnodeWithDiscoveryDisabled() throws UnknownHostException {
|
||||
EnodeURL enodeWithNoDiscovery = mock(EnodeURL.class);
|
||||
when(enodeWithNoDiscovery.getDiscoveryPort()).thenReturn(Optional.empty());
|
||||
when(enodeWithNoDiscovery.getListeningPort()).thenReturn(Optional.of(8545));
|
||||
|
||||
when(enodeWithNoDiscovery.getIp()).thenReturn(InetAddress.getLoopbackAddress());
|
||||
|
||||
Endpoint result = Endpoint.fromEnode(enodeWithNoDiscovery);
|
||||
|
||||
assertEquals("127.0.0.1", result.getHost());
|
||||
|
||||
assertEquals(EnodeURLImpl.DEFAULT_LISTENING_PORT, result.getUdpPort());
|
||||
|
||||
assertEquals(Optional.empty(), result.getTcpPort());
|
||||
}
|
||||
|
||||
protected void bondViaIncomingPing(
|
||||
final MockPeerDiscoveryAgent agent, final MockPeerDiscoveryAgent otherNode) {
|
||||
final Packet pingPacket = helper.createPingPacket(otherNode, agent);
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMer
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoOpBonsaiCachedWorldStorageManager;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiPreImageProxy;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateLayerStorage;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.common.cache.DiffBasedCachedWorldStorageManager;
|
||||
@@ -38,6 +37,8 @@ import org.hyperledger.besu.metrics.ObservableMetricsSystem;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.trielogs.TrieLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
@@ -47,13 +48,18 @@ import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
implements ReferenceTestWorldState {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BonsaiReferenceTestWorldState.class);
|
||||
|
||||
private final BonsaiReferenceTestWorldStateStorage refTestStorage;
|
||||
private final BonsaiPreImageProxy preImageProxy;
|
||||
private final EvmConfiguration evmConfiguration;
|
||||
private final Collection<Exception> exceptionCollector = new ArrayList<>();
|
||||
|
||||
protected BonsaiReferenceTestWorldState(
|
||||
final BonsaiReferenceTestWorldStateStorage worldStateKeyValueStorage,
|
||||
@@ -110,7 +116,8 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processExtraStateStorageFormatValidation(final BlockHeader blockHeader) {
|
||||
public Collection<Exception> processExtraStateStorageFormatValidation(
|
||||
final BlockHeader blockHeader) {
|
||||
if (blockHeader != null) {
|
||||
final Hash parentStateRoot = getWorldStateRootHash();
|
||||
final BonsaiReferenceTestUpdateAccumulator originalUpdater =
|
||||
@@ -121,6 +128,7 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
// validate trielog generation with frozen state
|
||||
validateStateRolling(parentStateRoot, originalUpdater, blockHeader, true);
|
||||
}
|
||||
return exceptionCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,9 +164,12 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
bonsaiWorldState.persist(blockHeader);
|
||||
Hash generatedRootHash = bonsaiWorldState.rootHash();
|
||||
if (!bonsaiWorldState.rootHash().equals(blockHeader.getStateRoot())) {
|
||||
throw new RuntimeException(
|
||||
final String msg =
|
||||
"state root becomes invalid following a rollForward %s != %s"
|
||||
.formatted(blockHeader.getStateRoot(), generatedRootHash));
|
||||
.formatted(blockHeader.getStateRoot(), generatedRootHash);
|
||||
final RuntimeException e = new RuntimeException(msg);
|
||||
exceptionCollector.add(e);
|
||||
LOG.atError().setMessage(msg).setCause(e).log();
|
||||
}
|
||||
|
||||
updaterForState = (BonsaiWorldStateUpdateAccumulator) bonsaiWorldState.updater();
|
||||
@@ -167,9 +178,12 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
bonsaiWorldState.persist(null);
|
||||
generatedRootHash = bonsaiWorldState.rootHash();
|
||||
if (!bonsaiWorldState.rootHash().equals(parentStateRoot)) {
|
||||
throw new RuntimeException(
|
||||
final String msg =
|
||||
"state root becomes invalid following a rollBackward %s != %s"
|
||||
.formatted(parentStateRoot, generatedRootHash));
|
||||
.formatted(parentStateRoot, generatedRootHash);
|
||||
final RuntimeException e = new RuntimeException(msg);
|
||||
exceptionCollector.add(e);
|
||||
LOG.atError().setMessage(msg).setCause(e).log();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,19 +203,11 @@ public class BonsaiReferenceTestWorldState extends BonsaiWorldState
|
||||
}
|
||||
|
||||
private BonsaiWorldState createBonsaiWorldState(final boolean isFrozen) {
|
||||
BonsaiWorldState bonsaiWorldState =
|
||||
new BonsaiWorldState(
|
||||
new BonsaiWorldStateLayerStorage(
|
||||
(BonsaiWorldStateKeyValueStorage) worldStateKeyValueStorage),
|
||||
bonsaiCachedMerkleTrieLoader,
|
||||
cachedWorldStorageManager,
|
||||
trieLogManager,
|
||||
evmConfiguration,
|
||||
new DiffBasedWorldStateConfig());
|
||||
final BonsaiReferenceTestWorldState copy = (BonsaiReferenceTestWorldState) this.copy();
|
||||
if (isFrozen) {
|
||||
bonsaiWorldState.freeze(); // freeze state
|
||||
copy.freeze();
|
||||
}
|
||||
return bonsaiWorldState;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
@@ -56,8 +58,10 @@ public class ForestReferenceTestWorldState extends ForestMutableWorldState
|
||||
* root has been validated, to ensure the integrity of other aspects of the state.
|
||||
*/
|
||||
@Override
|
||||
public void processExtraStateStorageFormatValidation(final BlockHeader blockHeader) {
|
||||
public Collection<Exception> processExtraStateStorageFormatValidation(
|
||||
final BlockHeader blockHeader) {
|
||||
// nothing more to verify with forest
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.hyperledger.besu.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -91,7 +92,7 @@ public interface ReferenceTestWorldState extends MutableWorldState {
|
||||
|
||||
ReferenceTestWorldState copy();
|
||||
|
||||
void processExtraStateStorageFormatValidation(final BlockHeader blockHeader);
|
||||
Collection<Exception> processExtraStateStorageFormatValidation(final BlockHeader blockHeader);
|
||||
|
||||
@JsonCreator
|
||||
static ReferenceTestWorldState create(final Map<String, AccountMock> accounts) {
|
||||
|
||||
@@ -75,6 +75,9 @@ public class StateTestVersionedTransaction {
|
||||
// String instead of VersionedHash because reference tests intentionally use bad hashes.
|
||||
private final List<String> blobVersionedHashes;
|
||||
|
||||
@JsonDeserialize(contentAs = org.hyperledger.besu.ethereum.core.CodeDelegation.class)
|
||||
private final List<org.hyperledger.besu.datatypes.CodeDelegation> authorizationList;
|
||||
|
||||
/**
|
||||
* Constructor for populating a mock transaction with json data.
|
||||
*
|
||||
@@ -103,7 +106,9 @@ public class StateTestVersionedTransaction {
|
||||
@JsonDeserialize(using = StateTestAccessListDeserializer.class) @JsonProperty("accessLists")
|
||||
final List<List<AccessListEntry>> maybeAccessLists,
|
||||
@JsonProperty("maxFeePerBlobGas") final String maxFeePerBlobGas,
|
||||
@JsonProperty("blobVersionedHashes") final List<String> blobVersionedHashes) {
|
||||
@JsonProperty("blobVersionedHashes") final List<String> blobVersionedHashes,
|
||||
@JsonProperty("authorizationList")
|
||||
final List<org.hyperledger.besu.datatypes.CodeDelegation> authorizationList) {
|
||||
|
||||
this.nonce = Bytes.fromHexStringLenient(nonce).toLong();
|
||||
this.gasPrice = Optional.ofNullable(gasPrice).map(Wei::fromHexString).orElse(null);
|
||||
@@ -124,6 +129,7 @@ public class StateTestVersionedTransaction {
|
||||
this.maxFeePerBlobGas =
|
||||
Optional.ofNullable(maxFeePerBlobGas).map(Wei::fromHexString).orElse(null);
|
||||
this.blobVersionedHashes = blobVersionedHashes;
|
||||
this.authorizationList = authorizationList;
|
||||
}
|
||||
|
||||
private static <T> List<T> parseArray(final String[] array, final Function<String, T> parseFct) {
|
||||
@@ -170,6 +176,7 @@ public class StateTestVersionedTransaction {
|
||||
// versioned hash string was bad, so this is an invalid transaction
|
||||
return null;
|
||||
}
|
||||
Optional.ofNullable(authorizationList).ifPresent(transactionBuilder::codeDelegations);
|
||||
|
||||
transactionBuilder.guessType();
|
||||
if (transactionBuilder.getTransactionType().requiresChainId()) {
|
||||
|
||||
@@ -22,6 +22,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.BlobGas;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
@@ -42,8 +49,12 @@ import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.testutil.JsonTestParameters;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class GeneralStateReferenceTestTools {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GeneralStateReferenceTestTools.class);
|
||||
|
||||
private static final List<String> SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS =
|
||||
Arrays.asList("Frontier", "Homestead", "EIP150");
|
||||
|
||||
@@ -179,16 +190,26 @@ public class GeneralStateReferenceTestTools {
|
||||
worldStateUpdater.deleteAccount(coinbase.getAddress());
|
||||
}
|
||||
worldStateUpdater.commit();
|
||||
worldState.processExtraStateStorageFormatValidation(blockHeader);
|
||||
Collection<Exception> additionalExceptions = worldState.processExtraStateStorageFormatValidation(blockHeader);
|
||||
worldState.persist(blockHeader);
|
||||
|
||||
// Check the world state root hash.
|
||||
final Hash expectedRootHash = spec.getExpectedRootHash();
|
||||
assertThat(worldState.rootHash())
|
||||
.withFailMessage(
|
||||
"Unexpected world state root hash; expected state: %s, computed state: %s",
|
||||
spec.getExpectedRootHash(), worldState.rootHash())
|
||||
.isEqualTo(expectedRootHash);
|
||||
// If the root hash doesn't match, first dump the world state for debugging.
|
||||
if (!expectedRootHash.equals(worldState.rootHash())) {
|
||||
logWorldState(worldState);
|
||||
}
|
||||
SoftAssertions.assertSoftly(
|
||||
softly -> {
|
||||
softly.assertThat(worldState.rootHash())
|
||||
.withFailMessage(
|
||||
"Unexpected world state root hash; expected state: %s, computed state: %s",
|
||||
spec.getExpectedRootHash(), worldState.rootHash())
|
||||
.isEqualTo(expectedRootHash);
|
||||
additionalExceptions.forEach(
|
||||
e -> softly.fail("Additional exception during state validation: " + e.getMessage()));
|
||||
|
||||
});
|
||||
|
||||
// Check the logs.
|
||||
final Hash expectedLogsHash = spec.getExpectedLogsHash();
|
||||
@@ -206,4 +227,33 @@ public class GeneralStateReferenceTestTools {
|
||||
private static boolean shouldClearEmptyAccounts(final String eip) {
|
||||
return !SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS.contains(eip);
|
||||
}
|
||||
|
||||
private static void logWorldState(final ReferenceTestWorldState worldState) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode worldStateJson = mapper.createObjectNode();
|
||||
worldState.streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE)
|
||||
.forEach(
|
||||
account -> {
|
||||
ObjectNode accountJson = mapper.createObjectNode();
|
||||
accountJson.put("nonce", Bytes.ofUnsignedLong(account.getNonce()).toShortHexString());
|
||||
accountJson.put("balance", account.getBalance().toShortHexString());
|
||||
accountJson.put("code", account.getCode().toHexString());
|
||||
ObjectNode storageJson = mapper.createObjectNode();
|
||||
var storageEntries = account.storageEntriesFrom(Bytes32.ZERO, Integer.MAX_VALUE);
|
||||
storageEntries.values().stream()
|
||||
.map(
|
||||
e ->
|
||||
Map.entry(
|
||||
e.getKey().orElse(UInt256.fromBytes(Bytes.EMPTY)),
|
||||
account.getStorageValue(UInt256.fromBytes(e.getKey().get()))))
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(e -> storageJson.put(e.getKey().toQuantityHexString(), e.getValue().toQuantityHexString()));
|
||||
|
||||
if (!storageEntries.isEmpty()) {
|
||||
accountJson.set("storage", storageJson);
|
||||
}
|
||||
worldStateJson.set(account.getAddress().orElse(Address.wrap(Bytes.EMPTY)).toHexString(), accountJson);
|
||||
});
|
||||
LOG.error("Calculated world state: \n{}", worldStateJson.toPrettyString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.hyperledger.besu.evm.internal.Words.clampedToLong;
|
||||
import static org.hyperledger.besu.evm.internal.Words.numWords;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Transaction;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
@@ -566,4 +567,25 @@ public class FrontierGasCalculator implements GasCalculator {
|
||||
public long getMinimumTransactionCost() {
|
||||
return TX_BASE_COST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long calculateGasRefund(
|
||||
final Transaction transaction,
|
||||
final MessageFrame initialFrame,
|
||||
final long codeDelegationRefund) {
|
||||
final long selfDestructRefund =
|
||||
getSelfDestructRefundAmount() * initialFrame.getSelfDestructs().size();
|
||||
final long baseRefundGas =
|
||||
initialFrame.getGasRefund() + selfDestructRefund + codeDelegationRefund;
|
||||
return refunded(transaction, initialFrame.getRemainingGas(), baseRefundGas);
|
||||
}
|
||||
|
||||
private long refunded(
|
||||
final Transaction transaction, final long gasRemaining, final long gasRefund) {
|
||||
// Integer truncation takes care of the floor calculation needed after the divide.
|
||||
final long maxRefundAllowance =
|
||||
(transaction.getGasLimit() - gasRemaining) / getMaxRefundQuotient();
|
||||
final long refundAllowance = Math.min(maxRefundAllowance, gasRefund);
|
||||
return gasRemaining + refundAllowance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.gascalculator;
|
||||
|
||||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Transaction;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
@@ -664,4 +665,15 @@ public interface GasCalculator {
|
||||
default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the gas refund for a transaction.
|
||||
*
|
||||
* @param transaction the transaction
|
||||
* @param initialFrame the initial frame
|
||||
* @param codeDelegationRefund the code delegation refund
|
||||
* @return the gas refund
|
||||
*/
|
||||
long calculateGasRefund(
|
||||
Transaction transaction, MessageFrame initialFrame, long codeDelegationRefund);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@ package org.hyperledger.besu.evm.precompile;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Encapsulates a group of {@link PrecompiledContract}s used together. */
|
||||
public class PrecompileContractRegistry {
|
||||
@@ -48,4 +50,13 @@ public class PrecompileContractRegistry {
|
||||
public void put(final Address address, final PrecompiledContract precompile) {
|
||||
precompiles.put(address, precompile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the addresses of the precompiled contracts.
|
||||
*
|
||||
* @return the addresses
|
||||
*/
|
||||
public Set<Address> getPrecompileAddresses() {
|
||||
return Collections.unmodifiableSet(precompiles.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -37,7 +38,8 @@ import org.slf4j.LoggerFactory;
|
||||
public class MessageCallProcessor extends AbstractMessageProcessor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MessageCallProcessor.class);
|
||||
|
||||
private final PrecompileContractRegistry precompiles;
|
||||
/** The precompiles. */
|
||||
protected final PrecompileContractRegistry precompiles;
|
||||
|
||||
/**
|
||||
* Instantiates a new Message call processor.
|
||||
@@ -171,4 +173,14 @@ public class MessageCallProcessor extends AbstractMessageProcessor {
|
||||
frame.setExceptionalHaltReason(result.getHaltReason());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the precompile addresses.
|
||||
*
|
||||
* @return the precompile addresses
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Set<Address> getPrecompileAddresses() {
|
||||
return precompiles.getPrecompileAddresses();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user