mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-08 21:38:15 -05:00
Fix javadoc for ethereum api module, graphql package (#7272)
* javadoc - Adding missing javadocs ethereum:api graphql package Signed-off-by: Usman Saleem <usman@usmans.info>
This commit is contained in:
62
build.gradle
62
build.gradle
@@ -365,9 +365,65 @@ allprojects {
|
||||
options.addBooleanOption('Xdoclint/package:-org.hyperledger.besu.privacy.contracts.generated,' +
|
||||
'-org.hyperledger.besu.tests.acceptance.*,' +
|
||||
'-org.hyperledger.besu.tests.web3j.generated,' +
|
||||
// TODO: these are temporary disabled (ethereum and sub modules), it should be removed in a future PR.
|
||||
'-org.hyperledger.besu.ethereum.*,' +
|
||||
'-org.hyperledger.besu.evmtool',
|
||||
// TODO: these are temporary excluded from lint (ethereum sub modules), it should be removed in a future PR.
|
||||
// ethereum api module
|
||||
'-org.hyperledger.besu.ethereum.api.handlers,' +
|
||||
'-org.hyperledger.besu.ethereum.api.jsonrpc,' +
|
||||
'-org.hyperledger.besu.ethereum.api.jsonrpc.*,' +
|
||||
'-org.hyperledger.besu.ethereum.api.query,' +
|
||||
'-org.hyperledger.besu.ethereum.api.query.*,' +
|
||||
'-org.hyperledger.besu.ethereum.api.tls,' +
|
||||
'-org.hyperledger.besu.ethereum.api.util,' +
|
||||
// ethereum blockcreation module
|
||||
'-org.hyperledger.besu.ethereum.blockcreation,' +
|
||||
'-org.hyperledger.besu.ethereum.blockcreation.*,' +
|
||||
// ethereum core module
|
||||
'-org.hyperledger.besu.ethereum.chain,' +
|
||||
'-org.hyperledger.besu.ethereum.core,' +
|
||||
'-org.hyperledger.besu.ethereum.core.*,' +
|
||||
'-org.hyperledger.besu.ethereum.debug,' +
|
||||
'-org.hyperledger.besu.ethereum.difficulty.fixed,' +
|
||||
'-org.hyperledger.besu.ethereum.forkid,' +
|
||||
'-org.hyperledger.besu.ethereum.mainnet,' +
|
||||
'-org.hyperledger.besu.ethereum.mainnet.*,' +
|
||||
'-org.hyperledger.besu.ethereum.privacy,' +
|
||||
'-org.hyperledger.besu.ethereum.privacy.*,' +
|
||||
'-org.hyperledger.besu.ethereum.processing,' +
|
||||
'-org.hyperledger.besu.ethereum.proof,' +
|
||||
'-org.hyperledger.besu.ethereum.storage,' +
|
||||
'-org.hyperledger.besu.ethereum.storage.*,' +
|
||||
'-org.hyperledger.besu.ethereum.transaction,' +
|
||||
'-org.hyperledger.besu.ethereum.trie.*,' +
|
||||
'-org.hyperledger.besu.ethereum.util,' +
|
||||
'-org.hyperledger.besu.ethereum.vm,' +
|
||||
'-org.hyperledger.besu.ethereum.worldstate,' +
|
||||
// ethereum eth module
|
||||
'-org.hyperledger.besu.ethereum.eth.*,' +
|
||||
'-org.hyperledger.besu.ethereum.eth,' +
|
||||
'-org.hyperledger.besu.consensus.merge,' +
|
||||
// evmtool module
|
||||
'-org.hyperledger.besu.evmtool,' +
|
||||
// p2p module
|
||||
'-org.hyperledger.besu.ethereum.p2p,' +
|
||||
'-org.hyperledger.besu.ethereum.p2p.*,' +
|
||||
// permissioning module
|
||||
'-org.hyperledger.besu.ethereum.permissioning,' +
|
||||
'-org.hyperledger.besu.ethereum.permissioning.*,' +
|
||||
// referencetests module
|
||||
'-org.hyperledger.besu.ethereum.referencetests,' +
|
||||
// retesteth module
|
||||
'-org.hyperledger.besu.ethereum.retesteth.methods,' +
|
||||
'-org.hyperledger.besu.ethereum.retesteth,' +
|
||||
//rlp module
|
||||
'-org.hyperledger.besu.ethereum.rlp,' +
|
||||
// stratum module
|
||||
'-org.hyperledger.besu.ethereum.stratum,' +
|
||||
// trie module
|
||||
'-org.hyperledger.besu.ethereum.trie.*,' +
|
||||
'-org.hyperledger.besu.ethereum.trie,' +
|
||||
// verkle trie module
|
||||
'-org.hyperledger.besu.ethereum.verkletrie,' +
|
||||
'-org.hyperledger.besu.ethereum.verkletrie.*',
|
||||
true)
|
||||
options.addStringOption('Xmaxerrs','65535')
|
||||
options.addStringOption('Xmaxwarns','65535')
|
||||
|
||||
@@ -18,58 +18,125 @@ import org.hyperledger.besu.datatypes.Wei;
|
||||
|
||||
import org.immutables.value.Value;
|
||||
|
||||
/**
|
||||
* The ApiConfiguration class provides configuration for the API. It includes default values for gas
|
||||
* price, max logs range, gas cap, and other parameters.
|
||||
*/
|
||||
@Value.Immutable
|
||||
@Value.Style(allParameters = true)
|
||||
public abstract class ApiConfiguration {
|
||||
|
||||
/**
|
||||
* The default lower bound coefficient for gas and priority fee. This value is used as the default
|
||||
* lower bound when calculating the gas and priority fee.
|
||||
*/
|
||||
public static final long DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = 0L;
|
||||
|
||||
/**
|
||||
* The default upper bound coefficient for gas and priority fee. This value is used as the default
|
||||
* upper bound when calculating the gas and priority fee.
|
||||
*/
|
||||
public static final long DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT = Long.MAX_VALUE;
|
||||
|
||||
/** Constructs a new ApiConfiguration with default values. */
|
||||
protected ApiConfiguration() {}
|
||||
|
||||
/**
|
||||
* Returns the number of blocks to consider for gas price calculations. Default value is 100.
|
||||
*
|
||||
* @return the number of blocks for gas price calculations
|
||||
*/
|
||||
@Value.Default
|
||||
public long getGasPriceBlocks() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the percentile to use for gas price calculations. Default value is 50.0.
|
||||
*
|
||||
* @return the percentile for gas price calculations
|
||||
*/
|
||||
@Value.Default
|
||||
public double getGasPricePercentile() {
|
||||
return 50.0d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum gas price. Default value is 500 GWei.
|
||||
*
|
||||
* @return the maximum gas price
|
||||
*/
|
||||
@Value.Default
|
||||
public Wei getGasPriceMax() {
|
||||
return Wei.of(500_000_000_000L); // 500 GWei
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fraction to use for gas price calculations. This is derived from the gas price
|
||||
* percentile.
|
||||
*
|
||||
* @return the fraction for gas price calculations
|
||||
*/
|
||||
@Value.Derived
|
||||
public double getGasPriceFraction() {
|
||||
return getGasPricePercentile() / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum range for logs. Default value is 5000.
|
||||
*
|
||||
* @return the maximum range for logs
|
||||
*/
|
||||
@Value.Default
|
||||
public Long getMaxLogsRange() {
|
||||
return 5000L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gas cap. Default value is 0.
|
||||
*
|
||||
* @return the gas cap
|
||||
*/
|
||||
@Value.Default
|
||||
public Long getGasCap() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether gas and priority fee limiting is enabled. Default value is false.
|
||||
*
|
||||
* @return true if gas and priority fee limiting is enabled, false otherwise
|
||||
*/
|
||||
@Value.Default
|
||||
public boolean isGasAndPriorityFeeLimitingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lower bound coefficient for gas and priority fee. Default value is 0.
|
||||
*
|
||||
* @return the lower bound coefficient for gas and priority fee
|
||||
*/
|
||||
@Value.Default
|
||||
public Long getLowerBoundGasAndPriorityFeeCoefficient() {
|
||||
return DEFAULT_LOWER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the upper bound coefficient for gas and priority fee. Default value is Long.MAX_VALUE.
|
||||
*
|
||||
* @return the upper bound coefficient for gas and priority fee
|
||||
*/
|
||||
@Value.Default
|
||||
public Long getUpperBoundGasAndPriorityFeeCoefficient() {
|
||||
return DEFAULT_UPPER_BOUND_GAS_AND_PRIORITY_FEE_COEFFICIENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum range for trace filter. Default value is 1000.
|
||||
*
|
||||
* @return the maximum range for trace filter
|
||||
*/
|
||||
@Value.Default
|
||||
public Long getMaxTraceFilterRange() {
|
||||
return 1000L;
|
||||
|
||||
@@ -26,17 +26,33 @@ import java.util.Objects;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
||||
/**
|
||||
* Represents the configuration for GraphQL. This class is used to set and get the configuration
|
||||
* details for GraphQL such as enabling GraphQL, setting the port and host, setting the allowed
|
||||
* domains for CORS, setting the hosts allowlist, and setting the HTTP timeout.
|
||||
*/
|
||||
public class GraphQLConfiguration {
|
||||
private static final String DEFAULT_GRAPHQL_HTTP_HOST = "127.0.0.1";
|
||||
|
||||
/** The default port number for the GraphQL HTTP server. */
|
||||
public static final int DEFAULT_GRAPHQL_HTTP_PORT = 8547;
|
||||
|
||||
private boolean enabled;
|
||||
private int port;
|
||||
private String host;
|
||||
private List<String> corsAllowedDomains = Collections.emptyList();
|
||||
private List<String> hostsAllowlist = Arrays.asList("localhost", "127.0.0.1");
|
||||
private List<String> hostsAllowlist = Arrays.asList("localhost", DEFAULT_GRAPHQL_HTTP_HOST);
|
||||
private long httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds();
|
||||
|
||||
/**
|
||||
* Creates a default configuration for GraphQL.
|
||||
*
|
||||
* <p>This method initializes a new GraphQLConfiguration object with default settings. The default
|
||||
* settings are: - GraphQL is not enabled - The port is set to the default GraphQL HTTP port - The
|
||||
* host is set to the default GraphQL HTTP host - The HTTP timeout is set to the default timeout
|
||||
*
|
||||
* @return a GraphQLConfiguration object with default settings
|
||||
*/
|
||||
public static GraphQLConfiguration createDefault() {
|
||||
final GraphQLConfiguration config = new GraphQLConfiguration();
|
||||
config.setEnabled(false);
|
||||
@@ -48,52 +64,112 @@ public class GraphQLConfiguration {
|
||||
|
||||
private GraphQLConfiguration() {}
|
||||
|
||||
/**
|
||||
* Checks if GraphQL is enabled.
|
||||
*
|
||||
* @return true if GraphQL is enabled, false otherwise
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled status of GraphQL.
|
||||
*
|
||||
* @param enabled the status to set. true to enable GraphQL, false to disable it
|
||||
*/
|
||||
public void setEnabled(final boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the port number for the GraphQL HTTP server.
|
||||
*
|
||||
* @return the port number
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the port number for the GraphQL HTTP server.
|
||||
*
|
||||
* @param port the port number to set
|
||||
*/
|
||||
public void setPort(final int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the host for the GraphQL HTTP server.
|
||||
*
|
||||
* @return the host
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the host for the GraphQL HTTP server.
|
||||
*
|
||||
* @param host the host to set
|
||||
*/
|
||||
public void setHost(final String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the allowed domains for CORS.
|
||||
*
|
||||
* @return a collection of allowed domains for CORS
|
||||
*/
|
||||
Collection<String> getCorsAllowedDomains() {
|
||||
return corsAllowedDomains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the allowed domains for CORS.
|
||||
*
|
||||
* @param corsAllowedDomains a list of allowed domains for CORS
|
||||
*/
|
||||
public void setCorsAllowedDomains(final List<String> corsAllowedDomains) {
|
||||
checkNotNull(corsAllowedDomains);
|
||||
this.corsAllowedDomains = corsAllowedDomains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hosts allowlist.
|
||||
*
|
||||
* @return a collection of hosts in the allowlist
|
||||
*/
|
||||
Collection<String> getHostsAllowlist() {
|
||||
return Collections.unmodifiableCollection(this.hostsAllowlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hosts allowlist.
|
||||
*
|
||||
* @param hostsAllowlist a list of hosts to be added to the allowlist
|
||||
*/
|
||||
public void setHostsAllowlist(final List<String> hostsAllowlist) {
|
||||
checkNotNull(hostsAllowlist);
|
||||
this.hostsAllowlist = hostsAllowlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the HTTP timeout in seconds.
|
||||
*
|
||||
* @return the HTTP timeout in seconds
|
||||
*/
|
||||
public Long getHttpTimeoutSec() {
|
||||
return httpTimeoutSec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP timeout in seconds.
|
||||
*
|
||||
* @param httpTimeoutSec the HTTP timeout to set in seconds
|
||||
*/
|
||||
public void setHttpTimeoutSec(final long httpTimeoutSec) {
|
||||
this.httpTimeoutSec = httpTimeoutSec;
|
||||
}
|
||||
|
||||
@@ -14,14 +14,33 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.graphql;
|
||||
|
||||
/** Internal GraphQL Context */
|
||||
/**
|
||||
* Enum representing various context types for GraphQL.
|
||||
*
|
||||
* <p>These context types are used internally by GraphQL to manage different aspects of the system.
|
||||
*/
|
||||
public enum GraphQLContextType {
|
||||
/** Represents blockchain queries context. */
|
||||
BLOCKCHAIN_QUERIES,
|
||||
|
||||
/** Represents protocol schedule context. */
|
||||
PROTOCOL_SCHEDULE,
|
||||
|
||||
/** Represents transaction pool context. */
|
||||
TRANSACTION_POOL,
|
||||
|
||||
/** Represents mining coordinator context. */
|
||||
MINING_COORDINATOR,
|
||||
|
||||
/** Represents synchronizer context. */
|
||||
SYNCHRONIZER,
|
||||
|
||||
/** Represents is alive handler context. */
|
||||
IS_ALIVE_HANDLER,
|
||||
|
||||
/** Represents chain ID context. */
|
||||
CHAIN_ID,
|
||||
|
||||
/** Represents gas cap context. */
|
||||
GAS_CAP
|
||||
}
|
||||
|
||||
@@ -21,18 +21,56 @@ import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
|
||||
/**
|
||||
* Interface representing the context for a GraphQL data fetcher.
|
||||
*
|
||||
* <p>This context provides access to various components of the system such as the transaction pool,
|
||||
* blockchain queries, mining coordinator, synchronizer, and protocol schedule.
|
||||
*/
|
||||
public interface GraphQLDataFetcherContext {
|
||||
|
||||
/**
|
||||
* Retrieves the transaction pool.
|
||||
*
|
||||
* @return the transaction pool
|
||||
*/
|
||||
TransactionPool getTransactionPool();
|
||||
|
||||
/**
|
||||
* Retrieves the blockchain queries.
|
||||
*
|
||||
* @return the blockchain queries
|
||||
*/
|
||||
BlockchainQueries getBlockchainQueries();
|
||||
|
||||
/**
|
||||
* Retrieves the mining coordinator.
|
||||
*
|
||||
* @return the mining coordinator
|
||||
*/
|
||||
MiningCoordinator getMiningCoordinator();
|
||||
|
||||
/**
|
||||
* Retrieves the synchronizer.
|
||||
*
|
||||
* @return the synchronizer
|
||||
*/
|
||||
Synchronizer getSynchronizer();
|
||||
|
||||
/**
|
||||
* Retrieves the protocol schedule.
|
||||
*
|
||||
* @return the protocol schedule
|
||||
*/
|
||||
ProtocolSchedule getProtocolSchedule();
|
||||
|
||||
/**
|
||||
* Retrieves the is alive handler.
|
||||
*
|
||||
* <p>By default, this method returns a new IsAliveHandler instance with a status of true.
|
||||
*
|
||||
* @return the is alive handler
|
||||
*/
|
||||
default IsAliveHandler getIsAliveHandler() {
|
||||
return new IsAliveHandler(true);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@ import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
|
||||
/**
|
||||
* Implementation of the GraphQLDataFetcherContext interface.
|
||||
*
|
||||
* <p>This class provides access to various components of the system such as the transaction pool,
|
||||
* blockchain queries, mining coordinator, synchronizer, and protocol schedule.
|
||||
*/
|
||||
public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext {
|
||||
|
||||
private final BlockchainQueries blockchainQueries;
|
||||
@@ -30,6 +36,12 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext
|
||||
private final TransactionPool transactionPool;
|
||||
private final IsAliveHandler isAliveHandler;
|
||||
|
||||
/**
|
||||
* Constructor that takes a GraphQLDataFetcherContext and an IsAliveHandler.
|
||||
*
|
||||
* @param context the GraphQLDataFetcherContext
|
||||
* @param isAliveHandler the IsAliveHandler
|
||||
*/
|
||||
public GraphQLDataFetcherContextImpl(
|
||||
final GraphQLDataFetcherContext context, final IsAliveHandler isAliveHandler) {
|
||||
this(
|
||||
@@ -41,6 +53,16 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext
|
||||
isAliveHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that takes a BlockchainQueries, ProtocolSchedule, TransactionPool,
|
||||
* MiningCoordinator, and Synchronizer.
|
||||
*
|
||||
* @param blockchainQueries the BlockchainQueries
|
||||
* @param protocolSchedule the ProtocolSchedule
|
||||
* @param transactionPool the TransactionPool
|
||||
* @param miningCoordinator the MiningCoordinator
|
||||
* @param synchronizer the Synchronizer
|
||||
*/
|
||||
public GraphQLDataFetcherContextImpl(
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
@@ -56,6 +78,17 @@ public class GraphQLDataFetcherContextImpl implements GraphQLDataFetcherContext
|
||||
new IsAliveHandler(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that takes a BlockchainQueries, ProtocolSchedule, TransactionPool,
|
||||
* MiningCoordinator, Synchronizer, and IsAliveHandler.
|
||||
*
|
||||
* @param blockchainQueries the BlockchainQueries
|
||||
* @param protocolSchedule the ProtocolSchedule
|
||||
* @param transactionPool the TransactionPool
|
||||
* @param miningCoordinator the MiningCoordinator
|
||||
* @param synchronizer the Synchronizer
|
||||
* @param isAliveHandler the IsAliveHandler
|
||||
*/
|
||||
public GraphQLDataFetcherContextImpl(
|
||||
final BlockchainQueries blockchainQueries,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
|
||||
@@ -61,10 +61,34 @@ import graphql.schema.DataFetcher;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
/**
|
||||
* This class contains data fetchers for GraphQL queries.
|
||||
*
|
||||
* <p>Data fetchers are responsible for fetching data for a specific field. Each field in the schema
|
||||
* is associated with a data fetcher. When the field is being processed during a query, the
|
||||
* associated data fetcher is invoked to get the data for that field.
|
||||
*
|
||||
* <p>This class contains data fetchers for various fields such as protocol version, syncing state,
|
||||
* pending state, gas price, chain ID, max priority fee per gas, range block, block, account, logs,
|
||||
* and transaction.
|
||||
*
|
||||
* <p>Each data fetcher is a method that returns a `DataFetcher` object. The `DataFetcher` object
|
||||
* defines how to fetch the data for the field. It takes a `DataFetchingEnvironment` object as input
|
||||
* which contains all the context needed to fetch the data.
|
||||
*/
|
||||
public class GraphQLDataFetchers {
|
||||
|
||||
private final Integer highestEthVersion;
|
||||
|
||||
/**
|
||||
* Constructs a new GraphQLDataFetchers instance.
|
||||
*
|
||||
* <p>This constructor takes a set of supported capabilities and determines the highest Ethereum
|
||||
* protocol version supported by these capabilities. This version is then stored and can be
|
||||
* fetched using the getProtocolVersionDataFetcher method.
|
||||
*
|
||||
* @param supportedCapabilities a set of capabilities supported by the Ethereum node
|
||||
*/
|
||||
public GraphQLDataFetchers(final Set<Capability> supportedCapabilities) {
|
||||
final OptionalInt version =
|
||||
supportedCapabilities.stream()
|
||||
@@ -74,10 +98,30 @@ public class GraphQLDataFetchers {
|
||||
highestEthVersion = version.isPresent() ? version.getAsInt() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches the highest Ethereum protocol version supported by the node.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input and returns the highest Ethereum protocol version as an
|
||||
* Optional<Integer>.
|
||||
*
|
||||
* @return a DataFetcher that fetches the highest Ethereum protocol version
|
||||
*/
|
||||
DataFetcher<Optional<Integer>> getProtocolVersionDataFetcher() {
|
||||
return dataFetchingEnvironment -> Optional.of(highestEthVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches the result of sending a raw transaction.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input and returns the hash of the transaction if it is valid
|
||||
* and added to the transaction pool. If the transaction is invalid, it throws a GraphQLException
|
||||
* with the invalid reason. If the raw transaction data cannot be read, it throws a
|
||||
* GraphQLException with INVALID_PARAMS error.
|
||||
*
|
||||
* @return a DataFetcher that fetches the result of sending a raw transaction
|
||||
*/
|
||||
DataFetcher<Optional<Bytes32>> getSendRawTransactionDataFetcher() {
|
||||
return dataFetchingEnvironment -> {
|
||||
try {
|
||||
@@ -99,6 +143,19 @@ public class GraphQLDataFetchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches the syncing state of the Ethereum node.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input and returns the syncing state as an
|
||||
* Optional<SyncStateAdapter>.
|
||||
*
|
||||
* <p>The SyncStateAdapter is a wrapper around the SyncStatus of the Ethereum node. It provides
|
||||
* information about the current syncing state of the node such as the current block, highest
|
||||
* block, and starting block.
|
||||
*
|
||||
* @return a DataFetcher that fetches the syncing state of the Ethereum node
|
||||
*/
|
||||
DataFetcher<Optional<SyncStateAdapter>> getSyncingDataFetcher() {
|
||||
return dataFetchingEnvironment -> {
|
||||
final Synchronizer synchronizer =
|
||||
@@ -125,6 +182,15 @@ public class GraphQLDataFetchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches the chain ID of the Ethereum node.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input and returns the chain ID as an {@code
|
||||
* Optional<BigInteger>}.
|
||||
*
|
||||
* @return a DataFetcher that fetches the chain ID of the Ethereum node
|
||||
*/
|
||||
public DataFetcher<Optional<BigInteger>> getChainIdDataFetcher() {
|
||||
return dataFetchingEnvironment -> {
|
||||
final GraphQLContext graphQLContext = dataFetchingEnvironment.getGraphQlContext();
|
||||
@@ -132,6 +198,15 @@ public class GraphQLDataFetchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input and returns the maximum priority fee per gas as a Wei
|
||||
* object. If the maximum priority fee per gas is not available, it returns Wei.ZERO.
|
||||
*
|
||||
* @return a DataFetcher that fetches the maximum priority fee per gas of the Ethereum node
|
||||
*/
|
||||
public DataFetcher<Wei> getMaxPriorityFeePerGasDataFetcher() {
|
||||
return dataFetchingEnvironment -> {
|
||||
final BlockchainQueries blockchainQuery =
|
||||
@@ -167,6 +242,20 @@ public class GraphQLDataFetchers {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataFetcher that fetches a specific block in the Ethereum blockchain.
|
||||
*
|
||||
* <p>The DataFetcher is a functional interface. It has a single method that takes a
|
||||
* DataFetchingEnvironment object as input. This method fetches a block based on either a block
|
||||
* number or a block hash. If both a block number and a block hash are provided, it throws a
|
||||
* GraphQLException with INVALID_PARAMS error. If neither a block number nor a block hash is
|
||||
* provided, it fetches the latest block.
|
||||
*
|
||||
* <p>The fetched block is then wrapped in a {@link NormalBlockAdapter} and returned as an {@code
|
||||
* Optional<NormalBlockAdapter>}.
|
||||
*
|
||||
* @return a DataFetcher that fetches a specific block in the Ethereum blockchain
|
||||
*/
|
||||
public DataFetcher<Optional<NormalBlockAdapter>> getBlockDataFetcher() {
|
||||
|
||||
return dataFetchingEnvironment -> {
|
||||
|
||||
@@ -68,6 +68,15 @@ import io.vertx.ext.web.handler.TimeoutHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class handles the HTTP service for GraphQL. It sets up the server, handles requests and
|
||||
* responses, and manages the lifecycle of the server.
|
||||
*
|
||||
* <p>It is responsible for processing GraphQL requests, executing them using the provided GraphQL
|
||||
* engine, and returning the results in the HTTP response.
|
||||
*
|
||||
* <p>It also handles errors and exceptions that may occur during the processing of a request.
|
||||
*/
|
||||
public class GraphQLHttpService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GraphQLHttpService.class);
|
||||
@@ -126,6 +135,15 @@ public class GraphQLHttpService {
|
||||
checkArgument(config.getHost() != null, "Required host is not configured.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the GraphQL HTTP service.
|
||||
*
|
||||
* <p>This method initializes the HTTP server and sets up the necessary routes for handling
|
||||
* GraphQL requests. It also validates the configuration and sets up the necessary handlers for
|
||||
* different types of requests.
|
||||
*
|
||||
* @return a CompletableFuture that will be completed when the server is successfully started.
|
||||
*/
|
||||
public CompletableFuture<?> start() {
|
||||
LOG.info("Starting GraphQL HTTP service on {}:{}", config.getHost(), config.getPort());
|
||||
// Create the HTTP server and a router object.
|
||||
@@ -230,6 +248,14 @@ public class GraphQLHttpService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the GraphQL HTTP service.
|
||||
*
|
||||
* <p>This method stops the HTTP server that was created and started by the start() method. If the
|
||||
* server is not running, this method will do nothing.
|
||||
*
|
||||
* @return a CompletableFuture that will be completed when the server is successfully stopped.
|
||||
*/
|
||||
public CompletableFuture<?> stop() {
|
||||
if (httpServer == null) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
@@ -248,6 +274,15 @@ public class GraphQLHttpService {
|
||||
return resultFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket address of the GraphQL HTTP service.
|
||||
*
|
||||
* <p>This method returns the socket address that the HTTP server is bound to. If the server is
|
||||
* not running, it returns an empty socket address.
|
||||
*
|
||||
* @return the socket address of the HTTP server, or an empty socket address if the server is not
|
||||
* running.
|
||||
*/
|
||||
public InetSocketAddress socketAddress() {
|
||||
if (httpServer == null) {
|
||||
return EMPTY_SOCKET_ADDRESS;
|
||||
@@ -255,6 +290,14 @@ public class GraphQLHttpService {
|
||||
return new InetSocketAddress(config.getHost(), httpServer.actualPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the GraphQL HTTP service.
|
||||
*
|
||||
* <p>This method constructs and returns the URL that the HTTP server is bound to. If the server
|
||||
* is not running, it returns an empty string.
|
||||
*
|
||||
* @return the URL of the HTTP server, or an empty string if the server is not running.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public String url() {
|
||||
if (httpServer == null) {
|
||||
|
||||
@@ -31,12 +31,30 @@ import graphql.schema.idl.SchemaParser;
|
||||
import graphql.schema.idl.TypeDefinitionRegistry;
|
||||
import graphql.schema.idl.TypeRuntimeWiring;
|
||||
|
||||
/**
|
||||
* This class provides the GraphQL service.
|
||||
*
|
||||
* <p>It contains a method to build the GraphQL service with the provided data fetchers.
|
||||
*/
|
||||
public class GraphQLProvider {
|
||||
|
||||
/**
|
||||
* The maximum complexity allowed for a GraphQL query.
|
||||
*
|
||||
* <p>This constant is used to prevent overly complex queries from being executed. A query's
|
||||
* complexity is calculated based on the number and type of fields it contains.
|
||||
*/
|
||||
public static final int MAX_COMPLEXITY = 200;
|
||||
|
||||
private GraphQLProvider() {}
|
||||
|
||||
/**
|
||||
* Builds the GraphQL service with the provided data fetchers.
|
||||
*
|
||||
* @param graphQLDataFetchers the data fetchers to be used in the GraphQL service.
|
||||
* @return the built GraphQL service.
|
||||
* @throws IOException if there is an error reading the schema file.
|
||||
*/
|
||||
public static GraphQL buildGraphQL(final GraphQLDataFetchers graphQLDataFetchers)
|
||||
throws IOException {
|
||||
final URL url = Resources.getResource("schema.graphqls");
|
||||
|
||||
@@ -35,6 +35,13 @@ import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/**
|
||||
* The Scalars class provides methods for creating GraphQLScalarType objects. These objects
|
||||
* represent the scalar types used in GraphQL, such as Address, BigInt, Bytes, Bytes32, and Long.
|
||||
* Each method in this class returns a GraphQLScalarType object that has been configured with a
|
||||
* specific Coercing implementation. The Coercing implementation defines how that type is
|
||||
* serialized, deserialized and validated.
|
||||
*/
|
||||
public class Scalars {
|
||||
|
||||
private Scalars() {}
|
||||
@@ -366,6 +373,14 @@ public class Scalars {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new GraphQLScalarType object for an Address.
|
||||
*
|
||||
* <p>The object is configured with a specific Coercing implementation that defines how the
|
||||
* Address type is serialized, deserialized and validated.
|
||||
*
|
||||
* @return a GraphQLScalarType object for an Address.
|
||||
*/
|
||||
public static GraphQLScalarType addressScalar() {
|
||||
return GraphQLScalarType.newScalar()
|
||||
.name("Address")
|
||||
@@ -374,6 +389,14 @@ public class Scalars {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GraphQLScalarType object for a BigInt.
|
||||
*
|
||||
* <p>The object is configured with a specific Coercing implementation that defines how the BigInt
|
||||
* type is serialized, deserialized and validated.
|
||||
*
|
||||
* @return a GraphQLScalarType object for a BigInt.
|
||||
*/
|
||||
public static GraphQLScalarType bigIntScalar() {
|
||||
return GraphQLScalarType.newScalar()
|
||||
.name("BigInt")
|
||||
@@ -382,6 +405,14 @@ public class Scalars {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GraphQLScalarType object for Bytes.
|
||||
*
|
||||
* <p>The object is configured with a specific Coercing implementation that defines how the Bytes
|
||||
* type is serialized, deserialized and validated.
|
||||
*
|
||||
* @return a GraphQLScalarType object for Bytes.
|
||||
*/
|
||||
public static GraphQLScalarType bytesScalar() {
|
||||
return GraphQLScalarType.newScalar()
|
||||
.name("Bytes")
|
||||
@@ -390,6 +421,14 @@ public class Scalars {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GraphQLScalarType object for Bytes32.
|
||||
*
|
||||
* <p>The object is configured with a specific Coercing implementation that defines how the
|
||||
* Bytes32 type is serialized, deserialized and validated.
|
||||
*
|
||||
* @return a GraphQLScalarType object for Bytes32.
|
||||
*/
|
||||
public static GraphQLScalarType bytes32Scalar() {
|
||||
return GraphQLScalarType.newScalar()
|
||||
.name("Bytes32")
|
||||
@@ -398,6 +437,14 @@ public class Scalars {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GraphQLScalarType object for a Long.
|
||||
*
|
||||
* <p>The object is configured with a specific Coercing implementation that defines how the Long
|
||||
* type is serialized, deserialized and validated.
|
||||
*
|
||||
* @return a GraphQLScalarType object for a Long.
|
||||
*/
|
||||
public static GraphQLScalarType longScalar() {
|
||||
return GraphQLScalarType.newScalar()
|
||||
.name("Long")
|
||||
|
||||
@@ -23,19 +23,40 @@ import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
/**
|
||||
* The AccessListEntryAdapter class extends the AdapterBase class. It provides methods to get the
|
||||
* storage keys and address from an AccessListEntry.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class AccessListEntryAdapter extends AdapterBase {
|
||||
|
||||
/** The AccessListEntry object that this adapter wraps. */
|
||||
private final AccessListEntry accessListEntry;
|
||||
|
||||
/**
|
||||
* Constructs a new AccessListEntryAdapter with the given AccessListEntry.
|
||||
*
|
||||
* @param accessListEntry the AccessListEntry to be adapted
|
||||
*/
|
||||
public AccessListEntryAdapter(final AccessListEntry accessListEntry) {
|
||||
this.accessListEntry = accessListEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage keys from the AccessListEntry.
|
||||
*
|
||||
* @return a list of storage keys
|
||||
*/
|
||||
public List<Bytes32> getStorageKeys() {
|
||||
final var storage = accessListEntry.storageKeys();
|
||||
return new ArrayList<>(storage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address from the AccessListEntry.
|
||||
*
|
||||
* @return an Optional containing the address if it exists, otherwise an empty Optional
|
||||
*/
|
||||
public Optional<Address> getAddress() {
|
||||
return Optional.of(accessListEntry.address());
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/**
|
||||
* The AccountAdapter class extends the AdapterBase class. It provides methods to get the account
|
||||
* details such as address, balance, transaction count, code, and storage.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class AccountAdapter extends AdapterBase {
|
||||
|
||||
@@ -35,18 +39,42 @@ public class AccountAdapter extends AdapterBase {
|
||||
private final Address address;
|
||||
private final Optional<Long> blockNumber;
|
||||
|
||||
/**
|
||||
* Constructs a new AccountAdapter with the given Account.
|
||||
*
|
||||
* @param account the Account to be adapted
|
||||
*/
|
||||
public AccountAdapter(final Account account) {
|
||||
this(account == null ? null : account.getAddress(), account, Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AccountAdapter with the given Account and block number.
|
||||
*
|
||||
* @param account the Account to be adapted
|
||||
* @param blockNumber the block number associated with the account
|
||||
*/
|
||||
public AccountAdapter(final Account account, final Optional<Long> blockNumber) {
|
||||
this(account == null ? null : account.getAddress(), account, blockNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AccountAdapter with the given address and Account.
|
||||
*
|
||||
* @param address the address of the account
|
||||
* @param account the Account to be adapted
|
||||
*/
|
||||
public AccountAdapter(final Address address, final Account account) {
|
||||
this(address, account, Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AccountAdapter with the given address, Account, and block number.
|
||||
*
|
||||
* @param address the address of the account
|
||||
* @param account the Account to be adapted
|
||||
* @param blockNumber the block number associated with the account
|
||||
*/
|
||||
public AccountAdapter(
|
||||
final Address address, final Account account, final Optional<Long> blockNumber) {
|
||||
this.account = Optional.ofNullable(account);
|
||||
@@ -54,18 +82,39 @@ public class AccountAdapter extends AdapterBase {
|
||||
this.blockNumber = blockNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the account.
|
||||
*
|
||||
* @return the address of the account
|
||||
*/
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the balance of the account.
|
||||
*
|
||||
* @return the balance of the account
|
||||
*/
|
||||
public Wei getBalance() {
|
||||
return account.map(AccountState::getBalance).orElse(Wei.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction count of the account.
|
||||
*
|
||||
* @return the transaction count of the account
|
||||
*/
|
||||
public Long getTransactionCount() {
|
||||
return account.map(AccountState::getNonce).orElse(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code of the account.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return the code of the account
|
||||
*/
|
||||
public Bytes getCode(final DataFetchingEnvironment environment) {
|
||||
|
||||
if (account.get() instanceof BonsaiAccount) {
|
||||
@@ -80,6 +129,12 @@ public class AccountAdapter extends AdapterBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage of the account.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return the storage of the account
|
||||
*/
|
||||
public Bytes32 getStorage(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final Bytes32 slot = environment.getArgument("slot");
|
||||
|
||||
@@ -48,15 +48,30 @@ import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/**
|
||||
* The BlockAdapterBase class extends the AdapterBase class. It provides methods to get and
|
||||
* manipulate block data.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class BlockAdapterBase extends AdapterBase {
|
||||
|
||||
private final BlockHeader header;
|
||||
|
||||
/**
|
||||
* Constructs a new BlockAdapterBase with the given BlockHeader.
|
||||
*
|
||||
* @param header the BlockHeader to be adapted
|
||||
*/
|
||||
BlockAdapterBase(final BlockHeader header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent block of the current block.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return an Optional containing the parent block if it exists, otherwise an empty Optional
|
||||
*/
|
||||
public Optional<NormalBlockAdapter> getParent(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final Hash parentHash = header.getParentHash();
|
||||
@@ -65,28 +80,59 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
return block.map(NormalBlockAdapter::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash of the current block.
|
||||
*
|
||||
* @return the hash of the block
|
||||
*/
|
||||
public Bytes32 getHash() {
|
||||
return header.getHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce of the current block.
|
||||
*
|
||||
* @return the nonce of the block
|
||||
*/
|
||||
public Bytes getNonce() {
|
||||
final long nonce = header.getNonce();
|
||||
final byte[] bytes = Longs.toByteArray(nonce);
|
||||
return Bytes.wrap(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transactions root of the current block.
|
||||
*
|
||||
* @return the transactions root of the block
|
||||
*/
|
||||
public Bytes32 getTransactionsRoot() {
|
||||
return header.getTransactionsRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state root of the current block.
|
||||
*
|
||||
* @return the state root of the block
|
||||
*/
|
||||
public Bytes32 getStateRoot() {
|
||||
return header.getStateRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the receipts root of the current block.
|
||||
*
|
||||
* @return the receipts root of the block
|
||||
*/
|
||||
public Bytes32 getReceiptsRoot() {
|
||||
return header.getReceiptsRoot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the miner of the current block.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return an AccountAdapter instance representing the miner of the block
|
||||
*/
|
||||
public AccountAdapter getMiner(final DataFetchingEnvironment environment) {
|
||||
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
@@ -102,46 +148,103 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
.orElseGet(() -> new EmptyAccountAdapter(header.getCoinbase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extra data of the current block.
|
||||
*
|
||||
* @return the extra data of the block
|
||||
*/
|
||||
public Bytes getExtraData() {
|
||||
return header.getExtraData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base fee per gas of the current block.
|
||||
*
|
||||
* @return the base fee per gas of the block
|
||||
*/
|
||||
public Optional<Wei> getBaseFeePerGas() {
|
||||
return header.getBaseFee();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gas limit of the current block.
|
||||
*
|
||||
* @return the gas limit of the block
|
||||
*/
|
||||
public Long getGasLimit() {
|
||||
return header.getGasLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gas used by the current block.
|
||||
*
|
||||
* @return the gas used by the block
|
||||
*/
|
||||
public Long getGasUsed() {
|
||||
return header.getGasUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the current block.
|
||||
*
|
||||
* @return the timestamp of the block
|
||||
*/
|
||||
public Long getTimestamp() {
|
||||
return header.getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the logs bloom of the current block.
|
||||
*
|
||||
* @return the logs bloom of the block
|
||||
*/
|
||||
public Bytes getLogsBloom() {
|
||||
return header.getLogsBloom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mix hash of the current block.
|
||||
*
|
||||
* @return the mix hash of the block
|
||||
*/
|
||||
public Bytes32 getMixHash() {
|
||||
return header.getMixHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difficulty of the current block.
|
||||
*
|
||||
* @return the difficulty of the block
|
||||
*/
|
||||
public Difficulty getDifficulty() {
|
||||
return header.getDifficulty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ommer hash of the current block.
|
||||
*
|
||||
* @return the ommer hash of the block
|
||||
*/
|
||||
public Bytes32 getOmmerHash() {
|
||||
return header.getOmmersHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the current block.
|
||||
*
|
||||
* @return the number of the block
|
||||
*/
|
||||
public Long getNumber() {
|
||||
return header.getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an AccountAdapter instance for a given address at the current block.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return an AccountAdapter instance representing the account of the given address at the current
|
||||
* block
|
||||
*/
|
||||
public AccountAdapter getAccount(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final long bn = header.getNumber();
|
||||
@@ -152,6 +255,13 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of logs for the current block that match a given filter.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return a list of LogAdapter instances representing the logs of the current block that match
|
||||
* the filter
|
||||
*/
|
||||
public List<LogAdapter> getLogs(final DataFetchingEnvironment environment) {
|
||||
|
||||
final Map<String, Object> filter = environment.getArgument("filter");
|
||||
@@ -183,11 +293,24 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimates the gas used for a call execution.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return the estimated gas used for the call execution
|
||||
*/
|
||||
public Long getEstimateGas(final DataFetchingEnvironment environment) {
|
||||
final Optional<CallResult> result = executeCall(environment);
|
||||
return result.map(CallResult::getGasUsed).orElse(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a call and returns the result.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return an Optional containing the result of the call execution if it exists, otherwise an
|
||||
* empty Optional
|
||||
*/
|
||||
public Optional<CallResult> getCall(final DataFetchingEnvironment environment) {
|
||||
return executeCall(environment);
|
||||
}
|
||||
@@ -259,12 +382,23 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw header of the current block.
|
||||
*
|
||||
* @return the raw header of the block
|
||||
*/
|
||||
Bytes getRawHeader() {
|
||||
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
|
||||
header.writeTo(rlpOutput);
|
||||
return rlpOutput.encoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of the current block.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return the raw data of the block
|
||||
*/
|
||||
Bytes getRaw(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
return query
|
||||
@@ -279,10 +413,22 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
.orElse(Bytes.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the withdrawals root of the current block.
|
||||
*
|
||||
* @return an Optional containing the withdrawals root if it exists, otherwise an empty Optional
|
||||
*/
|
||||
Optional<Bytes32> getWithdrawalsRoot() {
|
||||
return header.getWithdrawalsRoot().map(Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of withdrawals for the current block.
|
||||
*
|
||||
* @param environment the DataFetchingEnvironment
|
||||
* @return an Optional containing a list of WithdrawalAdapter instances representing the
|
||||
* withdrawals of the current block if they exist, otherwise an empty Optional
|
||||
*/
|
||||
Optional<List<WithdrawalAdapter>> getWithdrawals(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
return query
|
||||
@@ -295,10 +441,22 @@ public class BlockAdapterBase extends AdapterBase {
|
||||
.map(wl -> wl.stream().map(WithdrawalAdapter::new).toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the blob gas used by the current block.
|
||||
*
|
||||
* @return an Optional containing the blob gas used by the current block if it exists, otherwise
|
||||
* an empty Optional
|
||||
*/
|
||||
public Optional<Long> getBlobGasUsed() {
|
||||
return header.getBlobGasUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the excess blob gas of the current block.
|
||||
*
|
||||
* @return an Optional containing the excess blob gas of the current block if it exists, otherwise
|
||||
* an empty Optional
|
||||
*/
|
||||
public Optional<Long> getExcessBlobGas() {
|
||||
return header.getExcessBlobGas().map(BlobGas::toLong);
|
||||
}
|
||||
|
||||
@@ -16,26 +16,55 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
/**
|
||||
* Represents the result of a call execution. This class is used to encapsulate the status, gas
|
||||
* used, and data returned by a call execution. It is used in conjunction with the {@link
|
||||
* org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.BlockAdapterBase} class.
|
||||
*
|
||||
* @see org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.BlockAdapterBase
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class CallResult {
|
||||
private final Long status;
|
||||
private final Long gasUsed;
|
||||
private final Bytes data;
|
||||
|
||||
/**
|
||||
* Constructs a new CallResult.
|
||||
*
|
||||
* @param status the status of the call execution
|
||||
* @param gasUsed the amount of gas used by the call
|
||||
* @param data the data returned by the call
|
||||
*/
|
||||
CallResult(final Long status, final Long gasUsed, final Bytes data) {
|
||||
this.status = status;
|
||||
this.gasUsed = gasUsed;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the call execution.
|
||||
*
|
||||
* @return the status of the call execution
|
||||
*/
|
||||
public Long getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of gas used by the call.
|
||||
*
|
||||
* @return the amount of gas used by the call
|
||||
*/
|
||||
public Long getGasUsed() {
|
||||
return gasUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data returned by the call.
|
||||
*
|
||||
* @return the data returned by the call
|
||||
*/
|
||||
public Bytes getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,22 @@ import graphql.schema.DataFetchingEnvironment;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
/**
|
||||
* Represents an empty account in the Ethereum blockchain. This class is used when an account does
|
||||
* not exist at a specific address. It provides default values for the account's properties. It
|
||||
* extends the {@link org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.AccountAdapter}
|
||||
* class.
|
||||
*
|
||||
* @see org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.AccountAdapter
|
||||
*/
|
||||
public class EmptyAccountAdapter extends AccountAdapter {
|
||||
private final Address address;
|
||||
|
||||
/**
|
||||
* Constructs a new EmptyAccountAdapter.
|
||||
*
|
||||
* @param address the address of the account
|
||||
*/
|
||||
public EmptyAccountAdapter(final Address address) {
|
||||
super(null);
|
||||
this.address = address;
|
||||
|
||||
@@ -28,27 +28,62 @@ import java.util.Optional;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
/**
|
||||
* This class is an adapter for the LogWithMetadata class.
|
||||
*
|
||||
* <p>It extends the AdapterBase class and provides methods to get the index, topics, data,
|
||||
* transaction, and account associated with a log.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class LogAdapter extends AdapterBase {
|
||||
private final LogWithMetadata logWithMetadata;
|
||||
|
||||
/**
|
||||
* Constructor for LogAdapter.
|
||||
*
|
||||
* <p>It initializes the logWithMetadata field with the provided argument.
|
||||
*
|
||||
* @param logWithMetadata the log with metadata to be adapted.
|
||||
*/
|
||||
public LogAdapter(final LogWithMetadata logWithMetadata) {
|
||||
this.logWithMetadata = logWithMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the log.
|
||||
*
|
||||
* @return the index of the log.
|
||||
*/
|
||||
public Integer getIndex() {
|
||||
return logWithMetadata.getLogIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the topics of the log.
|
||||
*
|
||||
* @return a list of topics of the log.
|
||||
*/
|
||||
public List<LogTopic> getTopics() {
|
||||
final List<LogTopic> topics = logWithMetadata.getTopics();
|
||||
return new ArrayList<>(topics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data of the log.
|
||||
*
|
||||
* @return the data of the log.
|
||||
*/
|
||||
public Bytes getData() {
|
||||
return logWithMetadata.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transaction associated with the log.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return a TransactionAdapter for the transaction associated with the log.
|
||||
* @throws java.util.NoSuchElementException if the transaction is not found.
|
||||
*/
|
||||
public TransactionAdapter getTransaction(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final Hash hash = logWithMetadata.getTransactionHash();
|
||||
@@ -56,6 +91,12 @@ public class LogAdapter extends AdapterBase {
|
||||
return tran.map(TransactionAdapter::new).orElseThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the account associated with the log.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an AccountAdapter for the account associated with the log.
|
||||
*/
|
||||
public AccountAdapter getAccount(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
long blockNumber = logWithMetadata.getBlockNumber();
|
||||
|
||||
@@ -27,9 +27,24 @@ import java.util.Optional;
|
||||
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
|
||||
/**
|
||||
* This class is an adapter for the BlockWithMetadata class.
|
||||
*
|
||||
* <p>It extends the BlockAdapterBase class and provides methods to get the transaction count, total
|
||||
* difficulty, ommer count, ommers, transactions, and specific ommer and transaction at a given
|
||||
* index associated with a block.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class NormalBlockAdapter extends BlockAdapterBase {
|
||||
|
||||
/**
|
||||
* Constructor for NormalBlockAdapter.
|
||||
*
|
||||
* <p>It initializes the blockWithMetaData field with the provided argument and calls the parent
|
||||
* constructor with the header of the provided blockWithMetaData.
|
||||
*
|
||||
* @param blockWithMetaData the block with metadata to be adapted.
|
||||
*/
|
||||
public NormalBlockAdapter(
|
||||
final BlockWithMetadata<TransactionWithMetadata, Hash> blockWithMetaData) {
|
||||
super(blockWithMetaData.getHeader());
|
||||
@@ -38,18 +53,39 @@ public class NormalBlockAdapter extends BlockAdapterBase {
|
||||
|
||||
private final BlockWithMetadata<TransactionWithMetadata, Hash> blockWithMetaData;
|
||||
|
||||
/**
|
||||
* Returns the transaction count of the block.
|
||||
*
|
||||
* @return the transaction count of the block.
|
||||
*/
|
||||
public Optional<Integer> getTransactionCount() {
|
||||
return Optional.of(blockWithMetaData.getTransactions().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total difficulty of the block.
|
||||
*
|
||||
* @return the total difficulty of the block.
|
||||
*/
|
||||
public Difficulty getTotalDifficulty() {
|
||||
return blockWithMetaData.getTotalDifficulty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ommer count of the block.
|
||||
*
|
||||
* @return the ommer count of the block.
|
||||
*/
|
||||
public Optional<Integer> getOmmerCount() {
|
||||
return Optional.of(blockWithMetaData.getOmmers().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ommers of the block.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return a list of UncleBlockAdapter for the ommers of the block.
|
||||
*/
|
||||
public List<UncleBlockAdapter> getOmmers(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final List<Hash> ommers = blockWithMetaData.getOmmers();
|
||||
@@ -63,6 +99,12 @@ public class NormalBlockAdapter extends BlockAdapterBase {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ommer at a given index of the block.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an UncleBlockAdapter for the ommer at the given index of the block.
|
||||
*/
|
||||
public Optional<UncleBlockAdapter> getOmmerAt(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final int index = ((Number) environment.getArgument("index")).intValue();
|
||||
@@ -75,6 +117,13 @@ public class NormalBlockAdapter extends BlockAdapterBase {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of TransactionAdapter objects for the transactions in the block.
|
||||
*
|
||||
* <p>Each TransactionAdapter object is created by adapting a TransactionWithMetadata object.
|
||||
*
|
||||
* @return a list of TransactionAdapter objects for the transactions in the block.
|
||||
*/
|
||||
public List<TransactionAdapter> getTransactions() {
|
||||
final List<TransactionWithMetadata> trans = blockWithMetaData.getTransactions();
|
||||
final List<TransactionAdapter> results = new ArrayList<>();
|
||||
@@ -84,6 +133,16 @@ public class NormalBlockAdapter extends BlockAdapterBase {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a TransactionAdapter object for the transaction at the given index in the block.
|
||||
*
|
||||
* <p>The index is retrieved from the data fetching environment. If there is no transaction at the
|
||||
* given index, an empty Optional is returned.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a TransactionAdapter object for the transaction at the given
|
||||
* index in the block, or an empty Optional if there is no transaction at the given index.
|
||||
*/
|
||||
public Optional<TransactionAdapter> getTransactionAt(final DataFetchingEnvironment environment) {
|
||||
final int index = ((Number) environment.getArgument("index")).intValue();
|
||||
final List<TransactionWithMetadata> trans = blockWithMetaData.getTransactions();
|
||||
|
||||
@@ -36,19 +36,41 @@ import graphql.schema.DataFetchingEnvironment;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
|
||||
/**
|
||||
* This class represents the pending state of transactions in the Ethereum network.
|
||||
*
|
||||
* <p>It extends the AdapterBase class and provides methods to interact with the transaction pool.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class PendingStateAdapter extends AdapterBase {
|
||||
|
||||
private final TransactionPool transactionPool;
|
||||
|
||||
/**
|
||||
* Constructor for PendingStateAdapter.
|
||||
*
|
||||
* <p>It initializes the transactionPool field with the provided argument.
|
||||
*
|
||||
* @param transactionPool the transaction pool to be used.
|
||||
*/
|
||||
public PendingStateAdapter(final TransactionPool transactionPool) {
|
||||
this.transactionPool = transactionPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of transactions in the transaction pool.
|
||||
*
|
||||
* @return the count of transactions in the transaction pool.
|
||||
*/
|
||||
public Integer getTransactionCount() {
|
||||
return transactionPool.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of TransactionAdapter objects for the transactions in the transaction pool.
|
||||
*
|
||||
* @return a list of TransactionAdapter objects for the transactions in the transaction pool.
|
||||
*/
|
||||
public List<TransactionAdapter> getTransactions() {
|
||||
return transactionPool.getPendingTransactions().stream()
|
||||
.map(PendingTransaction::getTransaction)
|
||||
@@ -57,9 +79,17 @@ public class PendingStateAdapter extends AdapterBase {
|
||||
.toList();
|
||||
}
|
||||
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
/**
|
||||
* Returns an AccountAdapter object for the account associated with the provided address.
|
||||
*
|
||||
* <p>The account state is estimated against the latest block.
|
||||
*
|
||||
* @param dataFetchingEnvironment the data fetching environment.
|
||||
* @return an AccountAdapter object for the account associated with the provided address.
|
||||
*/
|
||||
public AccountAdapter getAccount(final DataFetchingEnvironment dataFetchingEnvironment) {
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
final BlockchainQueries blockchainQuery =
|
||||
dataFetchingEnvironment.getGraphQlContext().get(GraphQLContextType.BLOCKCHAIN_QUERIES);
|
||||
final Address addr = dataFetchingEnvironment.getArgument("address");
|
||||
@@ -71,16 +101,39 @@ public class PendingStateAdapter extends AdapterBase {
|
||||
.orElseGet(() -> new AccountAdapter(null));
|
||||
}
|
||||
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
/**
|
||||
* Estimates the gas required for a transaction.
|
||||
*
|
||||
* <p>This method calls the getCall method to simulate the transaction and then retrieves the gas
|
||||
* used by the transaction. The gas estimation is done against the latest block as there is
|
||||
* currently no way to expose the current "proposed block" for a speculative environment.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing the estimated gas for the transaction, or an empty Optional if
|
||||
* the transaction simulation was not successful.
|
||||
*/
|
||||
public Optional<Long> getEstimateGas(final DataFetchingEnvironment environment) {
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
final Optional<CallResult> result = getCall(environment);
|
||||
return result.map(CallResult::getGasUsed);
|
||||
}
|
||||
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
/**
|
||||
* Simulates the execution of a transaction.
|
||||
*
|
||||
* <p>This method retrieves the transaction parameters from the data fetching environment, creates
|
||||
* a CallParameter object, and then uses a TransactionSimulator to simulate the execution of the
|
||||
* transaction. The simulation is done against the latest block as there is currently no way to
|
||||
* expose the current "proposed block" for a speculative environment.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing the result of the transaction simulation, or an empty Optional
|
||||
* if the transaction simulation was not successful.
|
||||
*/
|
||||
public Optional<CallResult> getCall(final DataFetchingEnvironment environment) {
|
||||
// until the miner can expose the current "proposed block" we have no
|
||||
// speculative environment, so estimate against latest.
|
||||
final Map<String, Object> callData = environment.getArgument("data");
|
||||
final Address from = (Address) callData.get("from");
|
||||
final Address to = (Address) callData.get("to");
|
||||
|
||||
@@ -16,22 +16,52 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter;
|
||||
|
||||
import org.hyperledger.besu.plugin.data.SyncStatus;
|
||||
|
||||
/**
|
||||
* The SyncStateAdapter class provides methods to retrieve the synchronization status of the
|
||||
* blockchain.
|
||||
*
|
||||
* <p>This class is used to adapt a SyncStatus object into a format that can be used by GraphQL. The
|
||||
* SyncStatus object is provided at construction time.
|
||||
*
|
||||
* <p>The class provides methods to retrieve the starting block, current block, and highest block of
|
||||
* the synchronization status.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class SyncStateAdapter {
|
||||
private final SyncStatus syncStatus;
|
||||
|
||||
/**
|
||||
* Constructs a new SyncStateAdapter object.
|
||||
*
|
||||
* @param syncStatus the SyncStatus object to adapt.
|
||||
*/
|
||||
public SyncStateAdapter(final SyncStatus syncStatus) {
|
||||
this.syncStatus = syncStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the starting block of the synchronization status.
|
||||
*
|
||||
* @return the starting block of the synchronization status.
|
||||
*/
|
||||
public Long getStartingBlock() {
|
||||
return syncStatus.getStartingBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current block of the synchronization status.
|
||||
*
|
||||
* @return the current block of the synchronization status.
|
||||
*/
|
||||
public Long getCurrentBlock() {
|
||||
return syncStatus.getCurrentBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest block of the synchronization status.
|
||||
*
|
||||
* @return the highest block of the synchronization status.
|
||||
*/
|
||||
public Long getHighestBlock() {
|
||||
return syncStatus.getHighestBlock();
|
||||
}
|
||||
|
||||
@@ -38,11 +38,28 @@ import javax.annotation.Nonnull;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
/**
|
||||
* The TransactionAdapter class provides methods to retrieve the transaction details.
|
||||
*
|
||||
* <p>This class is used to adapt a TransactionWithMetadata object into a format that can be used by
|
||||
* GraphQL. The TransactionWithMetadata object is provided at construction time.
|
||||
*
|
||||
* <p>The class provides methods to retrieve the hash, type, nonce, index, from, to, value, gas
|
||||
* price, max fee per gas, max priority fee per gas, max fee per blob gas, effective tip, gas, input
|
||||
* data, block, status, gas used, cumulative gas used, effective gas price, blob gas used, blob gas
|
||||
* price, created contract, logs, R, S, V, Y parity, access list, raw, raw receipt, and blob
|
||||
* versioned hashes of the transaction.
|
||||
*/
|
||||
@SuppressWarnings("unused") // reflected by GraphQL
|
||||
public class TransactionAdapter extends AdapterBase {
|
||||
private final TransactionWithMetadata transactionWithMetadata;
|
||||
private Optional<TransactionReceiptWithMetadata> transactionReceiptWithMetadata;
|
||||
|
||||
/**
|
||||
* Constructs a new TransactionAdapter object.
|
||||
*
|
||||
* @param transactionWithMetadata the TransactionWithMetadata object to adapt.
|
||||
*/
|
||||
public TransactionAdapter(final @Nonnull TransactionWithMetadata transactionWithMetadata) {
|
||||
this.transactionWithMetadata = transactionWithMetadata;
|
||||
}
|
||||
@@ -65,22 +82,53 @@ public class TransactionAdapter extends AdapterBase {
|
||||
return transactionReceiptWithMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash of the transaction.
|
||||
*
|
||||
* @return the hash of the transaction.
|
||||
*/
|
||||
public Hash getHash() {
|
||||
return transactionWithMetadata.getTransaction().getHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the transaction.
|
||||
*
|
||||
* @return the type of the transaction.
|
||||
*/
|
||||
public Optional<Integer> getType() {
|
||||
return Optional.of(transactionWithMetadata.getTransaction().getType().ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce of the transaction.
|
||||
*
|
||||
* @return the nonce of the transaction.
|
||||
*/
|
||||
public Long getNonce() {
|
||||
return transactionWithMetadata.getTransaction().getNonce();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the transaction.
|
||||
*
|
||||
* @return the index of the transaction.
|
||||
*/
|
||||
public Optional<Integer> getIndex() {
|
||||
return transactionWithMetadata.getTransactionIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the sender of the transaction.
|
||||
*
|
||||
* <p>This method uses the BlockchainQueries to get the block number and then retrieves the sender
|
||||
* of the transaction. It then uses the getAndMapWorldState method to get the state of the
|
||||
* sender's account at the given block number.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an AccountAdapter object representing the sender's account state at the given block
|
||||
* number.
|
||||
*/
|
||||
public AccountAdapter getFrom(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final Long blockNumber =
|
||||
@@ -96,6 +144,18 @@ public class TransactionAdapter extends AdapterBase {
|
||||
.orElse(new EmptyAccountAdapter(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the recipient of the transaction.
|
||||
*
|
||||
* <p>This method uses the BlockchainQueries to get the block number and then retrieves the
|
||||
* recipient of the transaction. It then uses the getAndMapWorldState method to get the state of
|
||||
* the recipient's account at the given block number.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing an AccountAdapter object representing the recipient's account
|
||||
* state at the given block number, or an empty Optional if the transaction does not have a
|
||||
* recipient (i.e., it is a contract creation transaction).
|
||||
*/
|
||||
public Optional<AccountAdapter> getTo(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final Long blockNumber =
|
||||
@@ -115,39 +175,95 @@ public class TransactionAdapter extends AdapterBase {
|
||||
.or(() -> Optional.of(new EmptyAccountAdapter(address))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of the transaction.
|
||||
*
|
||||
* @return a Wei object representing the value of the transaction.
|
||||
*/
|
||||
public Wei getValue() {
|
||||
return transactionWithMetadata.getTransaction().getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the gas price of the transaction.
|
||||
*
|
||||
* @return a Wei object representing the gas price of the transaction. If the transaction does not
|
||||
* specify a gas price, this method returns zero.
|
||||
*/
|
||||
public Wei getGasPrice() {
|
||||
return transactionWithMetadata.getTransaction().getGasPrice().orElse(Wei.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the maximum fee per gas of the transaction.
|
||||
*
|
||||
* @return an Optional containing a Wei object representing the maximum fee per gas of the
|
||||
* transaction, or an empty Optional if the transaction does not specify a maximum fee per
|
||||
* gas.
|
||||
*/
|
||||
public Optional<Wei> getMaxFeePerGas() {
|
||||
return transactionWithMetadata.getTransaction().getMaxFeePerGas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the maximum priority fee per gas of the transaction.
|
||||
*
|
||||
* @return an Optional containing a Wei object representing the maximum priority fee per gas of
|
||||
* the transaction, or an empty Optional if the transaction does not specify a maximum
|
||||
* priority fee per gas.
|
||||
*/
|
||||
public Optional<Wei> getMaxPriorityFeePerGas() {
|
||||
return transactionWithMetadata.getTransaction().getMaxPriorityFeePerGas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the maximum fee per blob gas of the transaction.
|
||||
*
|
||||
* @return an Optional containing a Wei object representing the maximum fee per blob gas of the
|
||||
* transaction, or an empty Optional if the transaction does not specify a maximum fee per
|
||||
* blob gas.
|
||||
*/
|
||||
public Optional<Wei> getMaxFeePerBlobGas() {
|
||||
return transactionWithMetadata.getTransaction().getMaxFeePerBlobGas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the effective tip of the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Wei object representing the effective tip of the transaction,
|
||||
* or an empty Optional if the transaction does not specify an effective tip.
|
||||
*/
|
||||
public Optional<Wei> getEffectiveTip(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment)
|
||||
.map(rwm -> rwm.getTransaction().getEffectivePriorityFeePerGas(rwm.getBaseFee()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the gas limit of the transaction.
|
||||
*
|
||||
* @return a Long object representing the gas limit of the transaction.
|
||||
*/
|
||||
public Long getGas() {
|
||||
return transactionWithMetadata.getTransaction().getGasLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the input data of the transaction.
|
||||
*
|
||||
* @return a Bytes object representing the input data of the transaction.
|
||||
*/
|
||||
public Bytes getInputData() {
|
||||
return transactionWithMetadata.getTransaction().getPayload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the block of the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a NormalBlockAdapter object representing the block of the
|
||||
* transaction, or an empty Optional if the transaction does not specify a block.
|
||||
*/
|
||||
public Optional<NormalBlockAdapter> getBlock(final DataFetchingEnvironment environment) {
|
||||
return transactionWithMetadata
|
||||
.getBlockHash()
|
||||
@@ -155,6 +271,17 @@ public class TransactionAdapter extends AdapterBase {
|
||||
.map(NormalBlockAdapter::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the status of the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then checks
|
||||
* the status of the receipt. If the status is -1, it returns an empty Optional. Otherwise, it
|
||||
* returns an Optional containing the status of the receipt.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Long object representing the status of the transaction, or an
|
||||
* empty Optional if the status of the receipt is -1.
|
||||
*/
|
||||
public Optional<Long> getStatus(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment)
|
||||
.map(TransactionReceiptWithMetadata::getReceipt)
|
||||
@@ -165,27 +292,87 @@ public class TransactionAdapter extends AdapterBase {
|
||||
: Optional.of((long) receipt.getStatus()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the gas used by the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then
|
||||
* returns an Optional containing the gas used by the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Long object representing the gas used by the transaction.
|
||||
*/
|
||||
public Optional<Long> getGasUsed(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment).map(TransactionReceiptWithMetadata::getGasUsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the cumulative gas used by the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then
|
||||
* returns an Optional containing the cumulative gas used by the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Long object representing the cumulative gas used by the
|
||||
* transaction.
|
||||
*/
|
||||
public Optional<Long> getCumulativeGasUsed(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment).map(rpt -> rpt.getReceipt().getCumulativeGasUsed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the effective gas price of the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then
|
||||
* returns an Optional containing the effective gas price of the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Wei object representing the effective gas price of the
|
||||
* transaction.
|
||||
*/
|
||||
public Optional<Wei> getEffectiveGasPrice(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment)
|
||||
.map(rwm -> rwm.getTransaction().getEffectiveGasPrice(rwm.getBaseFee()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the blob gas used by the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then
|
||||
* returns an Optional containing the blob gas used by the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Long object representing the blob gas used by the transaction.
|
||||
*/
|
||||
public Optional<Long> getBlobGasUsed(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment).flatMap(TransactionReceiptWithMetadata::getBlobGasUsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the blob gas price of the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then
|
||||
* returns an Optional containing the blob gas price of the transaction.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Wei object representing the blob gas price of the transaction.
|
||||
*/
|
||||
public Optional<Wei> getBlobGasPrice(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment).flatMap(TransactionReceiptWithMetadata::getBlobGasPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contract created by the transaction.
|
||||
*
|
||||
* <p>This method checks if the transaction is a contract creation transaction. If it is, it
|
||||
* retrieves the address of the created contract. It then uses the BlockchainQueries to get the
|
||||
* block number and then retrieves the state of the created contract's account at the given block
|
||||
* number.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing an AccountAdapter object representing the created contract's
|
||||
* account state at the given block number, or an empty Optional if the transaction is not a
|
||||
* contract creation transaction or if the block number is not specified.
|
||||
*/
|
||||
public Optional<AccountAdapter> getCreatedContract(final DataFetchingEnvironment environment) {
|
||||
final boolean contractCreated = transactionWithMetadata.getTransaction().isContractCreation();
|
||||
if (contractCreated) {
|
||||
@@ -208,6 +395,17 @@ public class TransactionAdapter extends AdapterBase {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logs of the transaction.
|
||||
*
|
||||
* <p>This method uses the BlockchainQueries to get the block header and the receipt of the
|
||||
* transaction. It then retrieves the logs of the transaction and adapts them into a format that
|
||||
* can be used by GraphQL.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return a List of LogAdapter objects representing the logs of the transaction. If the
|
||||
* transaction does not have a receipt, this method returns an empty list.
|
||||
*/
|
||||
public List<LogAdapter> getLogs(final DataFetchingEnvironment environment) {
|
||||
final BlockchainQueries query = getBlockchainQueries(environment);
|
||||
final ProtocolSchedule protocolSchedule =
|
||||
@@ -240,14 +438,34 @@ public class TransactionAdapter extends AdapterBase {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the R component of the transaction's signature.
|
||||
*
|
||||
* @return a BigInteger object representing the R component of the transaction's signature.
|
||||
*/
|
||||
public BigInteger getR() {
|
||||
return transactionWithMetadata.getTransaction().getR();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the S component of the transaction's signature.
|
||||
*
|
||||
* @return a BigInteger object representing the S component of the transaction's signature.
|
||||
*/
|
||||
public BigInteger getS() {
|
||||
return transactionWithMetadata.getTransaction().getS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the V component of the transaction's signature.
|
||||
*
|
||||
* <p>If the transaction type is less than the BLOB transaction type and V is null, it returns the
|
||||
* Y parity of the transaction. Otherwise, it returns V.
|
||||
*
|
||||
* @return an Optional containing a BigInteger object representing the V component of the
|
||||
* transaction's signature, or an Optional containing the Y parity of the transaction if V is
|
||||
* null and the transaction type is less than the BLOB transaction type.
|
||||
*/
|
||||
public Optional<BigInteger> getV() {
|
||||
BigInteger v = transactionWithMetadata.getTransaction().getV();
|
||||
return Optional.ofNullable(
|
||||
@@ -258,10 +476,22 @@ public class TransactionAdapter extends AdapterBase {
|
||||
: v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Y parity of the transaction's signature.
|
||||
*
|
||||
* @return an Optional containing a BigInteger object representing the Y parity of the
|
||||
* transaction's signature.
|
||||
*/
|
||||
public Optional<BigInteger> getYParity() {
|
||||
return Optional.ofNullable(transactionWithMetadata.getTransaction().getYParity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the access list of the transaction.
|
||||
*
|
||||
* @return a List of AccessListEntryAdapter objects representing the access list of the
|
||||
* transaction.
|
||||
*/
|
||||
public List<AccessListEntryAdapter> getAccessList() {
|
||||
return transactionWithMetadata
|
||||
.getTransaction()
|
||||
@@ -270,12 +500,30 @@ public class TransactionAdapter extends AdapterBase {
|
||||
.orElse(List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the raw transaction data.
|
||||
*
|
||||
* <p>This method uses the writeTo method of the transaction to write the transaction data to a
|
||||
* BytesValueRLPOutput object. It then encodes the BytesValueRLPOutput object and returns it.
|
||||
*
|
||||
* @return an Optional containing a Bytes object representing the raw transaction data.
|
||||
*/
|
||||
public Optional<Bytes> getRaw() {
|
||||
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
|
||||
transactionWithMetadata.getTransaction().writeTo(rlpOutput);
|
||||
return Optional.of(rlpOutput.encoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the raw receipt of the transaction.
|
||||
*
|
||||
* <p>This method uses the getReceipt method to get the receipt of the transaction. It then writes
|
||||
* the receipt data to a BytesValueRLPOutput object using the writeToForNetwork method of the
|
||||
* receipt. It then encodes the BytesValueRLPOutput object and returns it.
|
||||
*
|
||||
* @param environment the data fetching environment.
|
||||
* @return an Optional containing a Bytes object representing the raw receipt of the transaction.
|
||||
*/
|
||||
public Optional<Bytes> getRawReceipt(final DataFetchingEnvironment environment) {
|
||||
return getReceipt(environment)
|
||||
.map(
|
||||
@@ -286,6 +534,11 @@ public class TransactionAdapter extends AdapterBase {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the versioned hashes of the transaction.
|
||||
*
|
||||
* @return a List of VersionedHash objects representing the versioned hashes of the transaction.
|
||||
*/
|
||||
public List<VersionedHash> getBlobVersionedHashes() {
|
||||
return transactionWithMetadata.getTransaction().getVersionedHashes().orElse(List.of());
|
||||
}
|
||||
|
||||
@@ -17,26 +17,60 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.plugin.data.Withdrawal;
|
||||
|
||||
/**
|
||||
* The WithdrawalAdapter class provides methods to retrieve the withdrawal details.
|
||||
*
|
||||
* <p>This class is used to adapt a Withdrawal object into a format that can be used by GraphQL. The
|
||||
* Withdrawal object is provided at construction time.
|
||||
*
|
||||
* <p>The class provides methods to retrieve the index, validator, address, and amount of the
|
||||
* withdrawal.
|
||||
*/
|
||||
public class WithdrawalAdapter {
|
||||
|
||||
Withdrawal withdrawal;
|
||||
|
||||
/**
|
||||
* Constructs a new WithdrawalAdapter object.
|
||||
*
|
||||
* @param withdrawal the Withdrawal object to adapt.
|
||||
*/
|
||||
public WithdrawalAdapter(final Withdrawal withdrawal) {
|
||||
this.withdrawal = withdrawal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the withdrawal.
|
||||
*
|
||||
* @return the index of the withdrawal.
|
||||
*/
|
||||
public Long getIndex() {
|
||||
return withdrawal.getIndex().toLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validator of the withdrawal.
|
||||
*
|
||||
* @return the validator of the withdrawal.
|
||||
*/
|
||||
public Long getValidator() {
|
||||
return withdrawal.getValidatorIndex().toLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the withdrawal.
|
||||
*
|
||||
* @return the address of the withdrawal.
|
||||
*/
|
||||
public Address getAddress() {
|
||||
return withdrawal.getAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of the withdrawal.
|
||||
*
|
||||
* @return the amount of the withdrawal.
|
||||
*/
|
||||
public Long getAmount() {
|
||||
return withdrawal.getAmount().getAsBigInteger().longValue();
|
||||
}
|
||||
|
||||
@@ -19,30 +19,96 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
|
||||
/**
|
||||
* Enum representing various types of GraphQL errors.
|
||||
*
|
||||
* <p>Each error is associated with a specific code and message. The code is an integer that
|
||||
* uniquely identifies the error. The message is a string that provides a human-readable description
|
||||
* of the error.
|
||||
*
|
||||
* <p>This enum includes standard errors such as INVALID_PARAMS and INTERNAL_ERROR, transaction
|
||||
* validation failures such as NONCE_TOO_LOW and INVALID_TRANSACTION_SIGNATURE, and private
|
||||
* transaction errors such as PRIVATE_TRANSACTION_FAILED and PRIVATE_NONCE_TOO_LOW.
|
||||
*
|
||||
* <p>The {@code of} method is used to map a {@code TransactionInvalidReason} to a corresponding
|
||||
* {@code GraphQLError}.
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
|
||||
public enum GraphQLError {
|
||||
// Standard errors
|
||||
/** Error code -32602. This error occurs when the parameters provided are invalid. */
|
||||
INVALID_PARAMS(-32602, "Invalid params"),
|
||||
|
||||
/** Error code -32603. This error occurs when there is an internal error. */
|
||||
INTERNAL_ERROR(-32603, "Internal error"),
|
||||
|
||||
// Transaction validation failures
|
||||
/** Error code -32001. This error occurs when the nonce value is too low. */
|
||||
NONCE_TOO_LOW(-32001, "Nonce too low"),
|
||||
|
||||
/** Error code -32002. This error occurs when the transaction signature is invalid. */
|
||||
INVALID_TRANSACTION_SIGNATURE(-32002, "Invalid signature"),
|
||||
|
||||
/** Error code -32003. This error occurs when the intrinsic gas exceeds the gas limit. */
|
||||
INTRINSIC_GAS_EXCEEDS_LIMIT(-32003, "Intrinsic gas exceeds gas limit"),
|
||||
|
||||
/**
|
||||
* Error code -32004. This error occurs when the upfront cost of the transaction exceeds the
|
||||
* account balance.
|
||||
*/
|
||||
TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE(-32004, "Upfront cost exceeds account balance"),
|
||||
|
||||
/**
|
||||
* Error code -32005. This error occurs when the transaction gas limit exceeds the block gas
|
||||
* limit.
|
||||
*/
|
||||
EXCEEDS_BLOCK_GAS_LIMIT(-32005, "Transaction gas limit exceeds block gas limit"),
|
||||
|
||||
/** Error code -32006. This error occurs when the nonce value is too high. */
|
||||
INCORRECT_NONCE(-32006, "Nonce too high"),
|
||||
|
||||
/**
|
||||
* Error code -32007. This error occurs when the sender account is not authorized to send
|
||||
* transactions.
|
||||
*/
|
||||
TX_SENDER_NOT_AUTHORIZED(-32007, "Sender account not authorized to send transactions"),
|
||||
|
||||
/** Error code -32008. This error occurs when the initial sync is still in progress. */
|
||||
CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE(-32008, "Initial sync is still in progress"),
|
||||
|
||||
/**
|
||||
* Error code -32009. This error occurs when the gas price is below the configured minimum gas
|
||||
* price.
|
||||
*/
|
||||
GAS_PRICE_TOO_LOW(-32009, "Gas price below configured minimum gas price"),
|
||||
|
||||
/**
|
||||
* Error code -32000. This error occurs when the Chain ID in the transaction signature is wrong.
|
||||
*/
|
||||
WRONG_CHAIN_ID(-32000, "Wrong Chain ID in transaction signature"),
|
||||
|
||||
/**
|
||||
* Error code -32000. This error occurs when signatures with replay protection are not supported.
|
||||
*/
|
||||
REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED(
|
||||
-32000, "Signatures with replay protection are not supported"),
|
||||
|
||||
/** Error code -32000. This error occurs when the transaction fee cap is exceeded. */
|
||||
TX_FEECAP_EXCEEDED(-32000, "Transaction fee cap exceeded"),
|
||||
|
||||
// Private Transaction Errors
|
||||
/** Error code -32000. This error occurs when a private transaction fails. */
|
||||
PRIVATE_TRANSACTION_FAILED(-32000, "Private transaction failed"),
|
||||
|
||||
/**
|
||||
* Error code -50100. This error occurs when the nonce value for a private transaction is too low.
|
||||
*/
|
||||
PRIVATE_NONCE_TOO_LOW(-50100, "Private transaction nonce too low"),
|
||||
|
||||
/**
|
||||
* Error code -50100. This error occurs when the nonce value for a private transaction is
|
||||
* incorrect.
|
||||
*/
|
||||
INCORRECT_PRIVATE_NONCE(-50100, "Private transaction nonce is incorrect");
|
||||
|
||||
private final int code;
|
||||
@@ -53,49 +119,52 @@ public enum GraphQLError {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code associated with this GraphQL error.
|
||||
*
|
||||
* @return the error code as an integer.
|
||||
*/
|
||||
@JsonGetter("code")
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message associated with this GraphQL error.
|
||||
*
|
||||
* @return the error message as a string.
|
||||
*/
|
||||
@JsonGetter("message")
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a {@code TransactionInvalidReason} to a corresponding {@code GraphQLError}.
|
||||
*
|
||||
* <p>This method is used to convert a transaction invalid reason to a GraphQL error, which can be
|
||||
* used to provide more detailed error information to the client.
|
||||
*
|
||||
* @param transactionInvalidReason the transaction invalid reason to be converted.
|
||||
* @return the corresponding GraphQL error.
|
||||
*/
|
||||
public static GraphQLError of(final TransactionInvalidReason transactionInvalidReason) {
|
||||
switch (transactionInvalidReason) {
|
||||
case WRONG_CHAIN_ID:
|
||||
return WRONG_CHAIN_ID;
|
||||
case REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED:
|
||||
return REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED;
|
||||
case INVALID_SIGNATURE:
|
||||
return INVALID_TRANSACTION_SIGNATURE;
|
||||
case UPFRONT_COST_EXCEEDS_BALANCE:
|
||||
return TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE;
|
||||
case NONCE_TOO_LOW:
|
||||
case PRIVATE_NONCE_TOO_LOW:
|
||||
return NONCE_TOO_LOW;
|
||||
case NONCE_TOO_HIGH:
|
||||
case PRIVATE_NONCE_TOO_HIGH:
|
||||
return INCORRECT_NONCE;
|
||||
case INTRINSIC_GAS_EXCEEDS_GAS_LIMIT:
|
||||
return INTRINSIC_GAS_EXCEEDS_LIMIT;
|
||||
case EXCEEDS_BLOCK_GAS_LIMIT:
|
||||
return EXCEEDS_BLOCK_GAS_LIMIT;
|
||||
case TX_SENDER_NOT_AUTHORIZED:
|
||||
return TX_SENDER_NOT_AUTHORIZED;
|
||||
case CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE:
|
||||
return CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE;
|
||||
return switch (transactionInvalidReason) {
|
||||
case WRONG_CHAIN_ID -> WRONG_CHAIN_ID;
|
||||
case REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED -> REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED;
|
||||
case INVALID_SIGNATURE -> INVALID_TRANSACTION_SIGNATURE;
|
||||
case UPFRONT_COST_EXCEEDS_BALANCE -> TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE;
|
||||
case NONCE_TOO_LOW, PRIVATE_NONCE_TOO_LOW -> NONCE_TOO_LOW;
|
||||
case NONCE_TOO_HIGH, PRIVATE_NONCE_TOO_HIGH -> INCORRECT_NONCE;
|
||||
case INTRINSIC_GAS_EXCEEDS_GAS_LIMIT -> INTRINSIC_GAS_EXCEEDS_LIMIT;
|
||||
case EXCEEDS_BLOCK_GAS_LIMIT -> EXCEEDS_BLOCK_GAS_LIMIT;
|
||||
case TX_SENDER_NOT_AUTHORIZED -> TX_SENDER_NOT_AUTHORIZED;
|
||||
case CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE -> CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE;
|
||||
// Private Transaction Invalid Reasons
|
||||
case PRIVATE_TRANSACTION_FAILED:
|
||||
return PRIVATE_TRANSACTION_FAILED;
|
||||
case GAS_PRICE_TOO_LOW:
|
||||
return GAS_PRICE_TOO_LOW;
|
||||
case TX_FEECAP_EXCEEDED:
|
||||
return TX_FEECAP_EXCEEDED;
|
||||
default:
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
case PRIVATE_TRANSACTION_FAILED -> PRIVATE_TRANSACTION_FAILED;
|
||||
case GAS_PRICE_TOO_LOW -> GAS_PRICE_TOO_LOW;
|
||||
case TX_FEECAP_EXCEEDED -> TX_FEECAP_EXCEEDED;
|
||||
default -> INTERNAL_ERROR;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,26 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* Represents a GraphQL error response. This class extends the GraphQLResponse class and overrides
|
||||
* the getType method to return ERROR.
|
||||
*/
|
||||
public class GraphQLErrorResponse extends GraphQLResponse {
|
||||
|
||||
/**
|
||||
* Constructs a new GraphQLErrorResponse with the specified errors.
|
||||
*
|
||||
* @param errors the errors to be included in the response.
|
||||
*/
|
||||
public GraphQLErrorResponse(final Object errors) {
|
||||
super(errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this GraphQL response.
|
||||
*
|
||||
* @return GraphQLResponseType.ERROR, indicating that this is an error response.
|
||||
*/
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public GraphQLResponseType getType() {
|
||||
|
||||
@@ -19,36 +19,77 @@ import java.util.Map;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
|
||||
/**
|
||||
* This class represents a GraphQL JSON request.
|
||||
*
|
||||
* <p>It contains the query, operation name, and variables for a GraphQL request. The query is a
|
||||
* string that represents the GraphQL query. The operation name is a string that represents the
|
||||
* operation to be performed. The variables is a map that contains the variables for the GraphQL
|
||||
* query.
|
||||
*/
|
||||
public class GraphQLJsonRequest {
|
||||
private String query;
|
||||
private String operationName;
|
||||
private Map<String, Object> variables;
|
||||
|
||||
/** Default constructor for GraphQLJsonRequest. */
|
||||
public GraphQLJsonRequest() {}
|
||||
|
||||
/**
|
||||
* Gets the query of the GraphQL request.
|
||||
*
|
||||
* @return the query of the GraphQL request.
|
||||
*/
|
||||
@JsonGetter
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query of the GraphQL request.
|
||||
*
|
||||
* @param query the query of the GraphQL request.
|
||||
*/
|
||||
@JsonSetter
|
||||
public void setQuery(final String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operation name of the GraphQL request.
|
||||
*
|
||||
* @return the operation name of the GraphQL request.
|
||||
*/
|
||||
@JsonGetter
|
||||
public String getOperationName() {
|
||||
return operationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operation name of the GraphQL request.
|
||||
*
|
||||
* @param operationName the operation name of the GraphQL request.
|
||||
*/
|
||||
@JsonSetter
|
||||
public void setOperationName(final String operationName) {
|
||||
this.operationName = operationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the variables of the GraphQL request.
|
||||
*
|
||||
* @return the variables of the GraphQL request.
|
||||
*/
|
||||
@JsonGetter
|
||||
public Map<String, Object> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the variables of the GraphQL request.
|
||||
*
|
||||
* @param variables the variables of the GraphQL request.
|
||||
*/
|
||||
@JsonSetter
|
||||
public void setVariables(final Map<String, Object> variables) {
|
||||
this.variables = variables;
|
||||
|
||||
@@ -14,8 +14,20 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.api.graphql.internal.response;
|
||||
|
||||
/**
|
||||
* This class represents a GraphQL response with no content.
|
||||
*
|
||||
* <p>It extends the GraphQLResponse class and overrides the getType method to return
|
||||
* GraphQLResponseType.NONE.
|
||||
*/
|
||||
public class GraphQLNoResponse extends GraphQLResponse {
|
||||
|
||||
/**
|
||||
* Default constructor for GraphQLNoResponse.
|
||||
*
|
||||
* <p>It calls the parent constructor with null as the argument, indicating no content for this
|
||||
* response.
|
||||
*/
|
||||
public GraphQLNoResponse() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,35 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a GraphQL response. This abstract class provides a structure for different types of
|
||||
* GraphQL responses.
|
||||
*/
|
||||
public abstract class GraphQLResponse {
|
||||
public abstract GraphQLResponseType getType();
|
||||
|
||||
private final Object result;
|
||||
|
||||
/**
|
||||
* Constructs a new GraphQLResponse with the specified result.
|
||||
*
|
||||
* @param result the result to be included in the response.
|
||||
*/
|
||||
GraphQLResponse(final Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this GraphQL response.
|
||||
*
|
||||
* @return the type of this GraphQL response as a GraphQLResponseType.
|
||||
*/
|
||||
public abstract GraphQLResponseType getType();
|
||||
|
||||
/**
|
||||
* Returns the result of this GraphQL response.
|
||||
*
|
||||
* @return the result of this GraphQL response as an Object.
|
||||
*/
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,15 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response;
|
||||
|
||||
/** Various types of responses that the JSON-RPC component may produce. */
|
||||
public enum GraphQLResponseType {
|
||||
/** Represents a response type where there is no content. */
|
||||
NONE,
|
||||
|
||||
/** Represents a successful response type. */
|
||||
SUCCESS,
|
||||
|
||||
/** Represents an error response type. */
|
||||
ERROR,
|
||||
|
||||
/** Represents an unauthorized response type. */
|
||||
UNAUTHORIZED
|
||||
}
|
||||
|
||||
@@ -16,12 +16,33 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
/**
|
||||
* This class represents a successful GraphQL response.
|
||||
*
|
||||
* <p>It extends the GraphQLResponse class and overrides the getType method to return
|
||||
* GraphQLResponseType.SUCCESS.
|
||||
*/
|
||||
public class GraphQLSuccessResponse extends GraphQLResponse {
|
||||
|
||||
/**
|
||||
* Constructor for GraphQLSuccessResponse.
|
||||
*
|
||||
* <p>It calls the parent constructor with the provided data as the argument.
|
||||
*
|
||||
* @param data the data to be included in the successful response.
|
||||
*/
|
||||
public GraphQLSuccessResponse(final Object data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the GraphQL response.
|
||||
*
|
||||
* <p>This method is overridden to return GraphQLResponseType.SUCCESS, indicating a successful
|
||||
* response.
|
||||
*
|
||||
* @return GraphQLResponseType.SUCCESS
|
||||
*/
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public GraphQLResponseType getType() {
|
||||
|
||||
@@ -55,6 +55,11 @@ public final class MockNetwork {
|
||||
private final Map<Peer, MockNetwork.MockP2PNetwork> nodes = new HashMap<>();
|
||||
private final List<Capability> capabilities;
|
||||
|
||||
/**
|
||||
* Constructs a new MockNetwork with the specified capabilities.
|
||||
*
|
||||
* @param capabilities a list of capabilities that the mock network should have.
|
||||
*/
|
||||
public MockNetwork(final List<Capability> capabilities) {
|
||||
this.capabilities = capabilities;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user