[23.4] Remove GoQuorum privacy (#5303)

* removed separate decoding logic

* run non-mainnet ATs to make sure

* remove goQuorum flag from everywhere

* remove GOQUORUM api group

* remove GoQuorum enclave, privacy params, RPCs and other related config

* removed Goquorum related error codes, rpcMethod codes, privateBloom

* removed v from transaction

* removed private GoQuorum storage provider

---------

Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
pull/5344/head
Sally MacFarlane 2 years ago committed by GitHub
parent 42f52e72be
commit 067a263374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 4
      besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
  3. 74
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  4. 54
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  5. 8
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  6. 58
      config/src/main/java/org/hyperledger/besu/config/GoQuorumOptions.java
  7. 9
      consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueProtocolSchedule.java
  8. 8
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BaseBftProtocolScheduleBuilder.java
  9. 1
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/CombinedProtocolScheduleFactoryTest.java
  10. 73
      consensus/ibft/src/main/java/org/hyperledger/besu/consensus/ibft/IbftLegacyContext.java
  11. 5
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeBlockProcessor.java
  12. 2
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/MergeProtocolSchedule.java
  13. 126
      enclave/src/integration-test/java/org/hyperledger/besu/enclave/GoQuorumEnclaveTest.java
  14. 40
      enclave/src/main/java/org/hyperledger/besu/enclave/EnclaveFactory.java
  15. 194
      enclave/src/main/java/org/hyperledger/besu/enclave/GoQuorumEnclave.java
  16. 84
      enclave/src/main/java/org/hyperledger/besu/enclave/types/GoQuorumReceiveResponse.java
  17. 71
      enclave/src/main/java/org/hyperledger/besu/enclave/types/GoQuorumSendRequest.java
  18. 58
      enclave/src/main/java/org/hyperledger/besu/enclave/types/GoQuorumSendSignedRequest.java
  19. 40
      enclave/src/main/java/org/hyperledger/besu/enclave/types/GoQuorumStoreRawRequest.java
  20. 55
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/GraphQLDataFetchers.java
  21. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/TransactionAdapter.java
  22. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcErrorConverter.java
  23. 1
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcApis.java
  24. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java
  25. 33
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetCode.java
  26. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacyIdProvider.java
  27. 79
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/GoQuorumEthGetQuorumPayload.java
  28. 161
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/GoQuorumSendRawPrivateTransaction.java
  29. 75
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/GoQuorumStoreRawPrivateTransaction.java
  30. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcError.java
  31. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EthJsonRpcMethods.java
  32. 71
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/GoQuorumJsonRpcPrivacyMethods.java
  33. 5
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/JsonRpcMethodsFactory.java
  34. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java
  35. 16
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/TraceJsonRpcMethods.java
  36. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
  37. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/cache/TransactionLogBloomCacher.java
  38. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/util/DomainObjectDecodeUtils.java
  39. 3
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/JsonRpcErrorConverterTest.java
  40. 6
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthSendRawTransactionTest.java
  41. 150
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/goquorum/GoQuorumEthGetQuorumPayloadTest.java
  42. 298
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/goquorum/GoQuorumSendRawPrivateTransactionTest.java
  43. 2
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/RewardTraceGeneratorTest.java
  44. 132
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/GoQuorumPrivateTxBloomBlockchainQueriesTest.java
  45. 178
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/query/cache/GoQuorumPrivateTransactionLogBloomCacherTest.java
  46. 90
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/BlockTransactionSelector.java
  47. 1
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreatorTest.java
  48. 2
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java
  49. 4
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/PoWBlockCreatorTest.java
  50. 21
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/MainnetBlockValidator.java
  51. 29
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java
  52. 56
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/GoQuorumPrivacyParameters.java
  53. 19
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java
  54. 86
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
  55. 25
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java
  56. 1
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java
  57. 44
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumBlockProcessingResult.java
  58. 303
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumBlockProcessor.java
  59. 61
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumBlockValidator.java
  60. 81
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumPrivateKeyValueStorage.java
  61. 69
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumPrivateStateUtil.java
  62. 36
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumPrivateStorage.java
  63. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractProtocolScheduleBuilder.java
  64. 53
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java
  65. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessor.java
  66. 1
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSchedule.java
  67. 88
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java
  68. 131
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  69. 45
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  70. 27
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidator.java
  71. 18
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java
  72. 12
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSpecBuilder.java
  73. 9
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/TimestampScheduleBuilder.java
  74. 52
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/GoQuorumSendRawTxArgs.java
  75. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/StorageProvider.java
  76. 72
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/GoQuorumKeyValueStoragePrefixedKeyBlockchainStorage.java
  77. 57
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/GoQuorumKeyValueStorageProvider.java
  78. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueSegmentIdentifier.java
  79. 23
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProvider.java
  80. 32
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/storage/keyvalue/KeyValueStorageProviderBuilder.java
  81. 34
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/GoQuorumPrivateTransactionDetector.java
  82. 52
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulator.java
  83. 53
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/GoQuorumMutablePrivateAndPublicWorldStateUpdater.java
  84. 48
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/worldstate/GoQuorumMutablePrivateWorldStateUpdater.java
  85. 1
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ExecutionContextTestFixture.java
  86. 1
      ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java
  87. 1
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java
  88. 89
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/TransactionGoQuorumTest.java
  89. 23
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoderTest.java
  90. 165
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/goquorum/GoQuorumBlockProcessorTest.java
  91. 3
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultTimestampScheduleTest.java
  92. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetBlockProcessorTest.java
  93. 141
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionValidatorTest.java
  94. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MutableProtocolScheduleTest.java
  95. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilderTest.java
  96. 2
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/TimestampScheduleBuilderTest.java
  97. 5
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/transaction/TransactionSimulatorTest.java
  98. 10
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/TransactionPool.java
  99. 1
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/messages/MessageWrapperTest.java
  100. 3
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/AbstractTransactionPoolTest.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,7 +3,8 @@
## 23.4-RC
### Breaking Changes
- Removed IBFT1 feature [#5302](https://github.com/hyperledger/besu/pull/5302)
- Remove IBFT 1.0 feature (deprecated in 23.1.0-beta) [#5302](https://github.com/hyperledger/besu/pull/5302)
- Remove GoQuorum-compatible privacy feature (deprecated in 23.1.0-beta) [#5303](https://github.com/hyperledger/besu/pull/5303)
### Additions and Improvements
- Update most dependencies to latest version [#5269](https://github.com/hyperledger/besu/pull/5269)

@ -936,9 +936,7 @@ public class RunnerBuilder {
Optional<GraphQLHttpService> graphQLHttpService = Optional.empty();
if (graphQLConfiguration.isEnabled()) {
final GraphQLDataFetchers fetchers =
new GraphQLDataFetchers(
supportedCapabilities, privacyParameters.getGoQuorumPrivacyParameters());
final GraphQLDataFetchers fetchers = new GraphQLDataFetchers(supportedCapabilities);
final Map<GraphQLContextType, Object> graphQlContextMap = new ConcurrentHashMap<>();
graphQlContextMap.putIfAbsent(GraphQLContextType.BLOCKCHAIN_QUERIES, blockchainQueries);
graphQlContextMap.putIfAbsent(GraphQLContextType.PROTOCOL_SCHEDULE, protocolSchedule);

@ -89,7 +89,6 @@ import org.hyperledger.besu.cli.util.VersionProvider;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfiguration;
import org.hyperledger.besu.consensus.qbft.pki.PkiBlockCreationConfigurationProvider;
@ -106,7 +105,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
@ -122,7 +120,6 @@ import org.hyperledger.besu.ethereum.api.tls.FileBasedPasswordProvider;
import org.hyperledger.besu.ethereum.api.tls.TlsClientAuthConfiguration;
import org.hyperledger.besu.ethereum.api.tls.TlsConfiguration;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
@ -141,15 +138,10 @@ import org.hyperledger.besu.ethereum.permissioning.PermissioningConfigurationBui
import org.hyperledger.besu.ethereum.permissioning.SmartContractPermissioningConfiguration;
import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.worldstate.DefaultWorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.PrunerConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract;
import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract;
import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract;
@ -213,7 +205,6 @@ import java.security.NoSuchAlgorithmException;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -235,7 +226,6 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
@ -2211,44 +2201,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
vertx.isNativeTransportEnabled() && enabled, actualPath, rpcIpcApis);
}
private GoQuorumPrivacyParameters configureGoQuorumPrivacy(
final KeyValueStorageProvider storageProvider) {
return new GoQuorumPrivacyParameters(
createGoQuorumEnclave(),
readEnclaveKey(),
storageProvider.createGoQuorumPrivateStorage(),
createPrivateWorldStateArchive(storageProvider));
}
private GoQuorumEnclave createGoQuorumEnclave() {
final EnclaveFactory enclaveFactory = new EnclaveFactory(Vertx.vertx());
if (privacyOptionGroup.privacyKeyStoreFile != null) {
return enclaveFactory.createGoQuorumEnclave(
privacyOptionGroup.privacyUrl,
privacyOptionGroup.privacyKeyStoreFile,
privacyOptionGroup.privacyKeyStorePasswordFile,
privacyOptionGroup.privacyTlsKnownEnclaveFile);
} else {
return enclaveFactory.createGoQuorumEnclave(privacyOptionGroup.privacyUrl);
}
}
private String readEnclaveKey() {
final String key;
try {
key = Files.asCharSource(privacyOptionGroup.privacyPublicKeyFile, UTF_8).read();
} catch (final Exception e) {
throw new ParameterException(
this.commandLine,
"--privacy-public-key-file must be set if isQuorum is set in the genesis file.",
e);
}
// throws exception if invalid base 64
Base64.getDecoder().decode(key);
return key;
}
private void ensureAllNodesAreInAllowlist(
final Collection<EnodeURL> enodeAddresses,
final LocalPermissioningConfiguration permissioningConfiguration) {
@ -2314,7 +2266,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.nodeKey(new NodeKey(securityModule()))
.metricsSystem(metricsSystem.get())
.messagePermissioningProviders(permissioningService.getMessagePermissioningProviders())
.privacyParameters(privacyParameters(storageProvider))
.privacyParameters(privacyParameters())
.pkiBlockCreationConfiguration(maybePkiBlockCreationConfiguration())
.clock(Clock.systemUTC())
.isRevertReasonEnabled(isRevertReasonEnabled)
@ -2807,7 +2759,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|| permissionsOptionGroup.permissionsAccountsContractEnabled;
}
private PrivacyParameters privacyParameters(final KeyValueStorageProvider storageProvider) {
private PrivacyParameters privacyParameters() {
CommandLineUtils.checkOptionDependencies(
logger,
@ -2836,7 +2788,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
if (isGoQuorumCompatibilityMode) {
throw new ParameterException(
commandLine, String.format("%s %s", "GoQuorum mode", errorSuffix));
commandLine, String.format("GoQuorum privacy is no longer supported in Besu"));
}
if (Boolean.TRUE.equals(privacyOptionGroup.isPrivacyMultiTenancyEnabled)
@ -2898,20 +2850,12 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
privacyOptionGroup.privacyTlsKnownEnclaveFile);
}
privacyParametersBuilder.setEnclaveFactory(new EnclaveFactory(vertx));
} else if (isGoQuorumCompatibilityMode) {
privacyParametersBuilder.setGoQuorumPrivacyParameters(
Optional.of(configureGoQuorumPrivacy(storageProvider)));
}
if (Boolean.FALSE.equals(privacyOptionGroup.isPrivacyEnabled) && anyPrivacyApiEnabled()) {
logger.warn("Privacy is disabled. Cannot use EEA/PRIV API methods when not using Privacy.");
}
if (!isGoQuorumCompatibilityMode
&& (jsonRPCHttpOptionGroup.rpcHttpApis.contains(RpcApis.GOQUORUM.name())
|| jsonRPCWebsocketOptionGroup.rpcWsApis.contains(RpcApis.GOQUORUM.name()))) {
logger.warn("Cannot use GOQUORUM API methods when not in GoQuorum mode.");
}
privacyParametersBuilder.setPrivacyService(privacyPluginService);
final PrivacyParameters privacyParameters = privacyParametersBuilder.build();
@ -2924,14 +2868,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
return privacyParameters;
}
private WorldStateArchive createPrivateWorldStateArchive(final StorageProvider storageProvider) {
final WorldStateStorage privateWorldStateStorage =
storageProvider.createPrivateWorldStateStorage();
final WorldStatePreimageStorage preimageStorage =
storageProvider.createPrivateWorldStatePreimageStorage();
return new DefaultWorldStateArchive(privateWorldStateStorage, preimageStorage);
}
private boolean anyPrivacyApiEnabled() {
return jsonRPCHttpOptionGroup.rpcHttpApis.contains(RpcApis.EEA.name())
|| jsonRPCWebsocketOptionGroup.rpcWsApis.contains(RpcApis.EEA.name())
@ -2968,7 +2904,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
"No KeyValueStorageFactory found for key: " + name)))
.withCommonConfiguration(pluginCommonConfiguration)
.withMetricsSystem(getMetricsSystem())
.isGoQuorumCompatibilityMode(isGoQuorumCompatibilityMode.booleanValue())
.build();
}
return this.keyValueStorageProvider;
@ -3508,8 +3443,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
/** Enables Go Quorum Compatibility mode. Visible for testing. */
@VisibleForTesting
protected void enableGoQuorumCompatibilityMode() {
// this static flag is read by the RLP decoder
GoQuorumOptions.setGoQuorumCompatibilityMode(true);
// this static flag is still used for GoQuorum permissioning compatibility
isGoQuorumCompatibilityMode = true;
}

@ -4545,13 +4545,7 @@ public class BesuCommandTest extends CommandTestAbstract {
"--privacy-enabled", "--genesis-file", genesisFile.toString(), "--min-gas-price", "0");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("GoQuorum mode cannot be enabled with privacy.");
assertThat(commandOutput.toString(UTF_8)).isEmpty();
verify(mockLogger, atLeast(1))
.warn(
DEPRECATION_WARNING_MSG,
"isQuorum mode in genesis file (GoQuorum-compatible privacy mode)",
"--privacy-enabled");
.contains("GoQuorum privacy is no longer supported in Besu");
}
@Rule public TemporaryFolder testFolder = new TemporaryFolder();
@ -5142,52 +5136,6 @@ public class BesuCommandTest extends CommandTestAbstract {
"--min-gas-price must be set to zero if isQuorum mode is enabled in the genesis file.");
}
@Test
public void quorumInteropEnabledSucceedsWithGasPriceSetToZero() throws IOException {
final Path genesisFile =
createFakeGenesisFile(VALID_GENESIS_QUORUM_INTEROP_ENABLED_WITH_CHAINID);
parseCommand(
"--genesis-file",
genesisFile.toString(),
"--min-gas-price",
"0",
"--privacy-public-key-file",
ENCLAVE_PUBLIC_KEY_PATH);
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void quorumInteropEnabledFailsIfEnclaveKeyFileDoesNotExist() throws IOException {
final Path genesisFile =
createFakeGenesisFile(VALID_GENESIS_QUORUM_INTEROP_ENABLED_WITH_CHAINID);
parseCommand(
"--genesis-file",
genesisFile.toString(),
"--min-gas-price",
"0",
"--privacy-public-key-file",
"ThisFileDoesNotExist");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--privacy-public-key-file must be set if isQuorum is set in the genesis file.");
}
@Test
public void quorumInteropEnabledFailsIfEnclaveKeyFileIsNotSet() throws IOException {
final Path genesisFile =
createFakeGenesisFile(VALID_GENESIS_QUORUM_INTEROP_ENABLED_WITH_CHAINID);
parseCommand("--genesis-file", genesisFile.toString(), "--min-gas-price", "0");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("--privacy-public-key-file must be set if isQuorum is set in the genesis file.");
}
@Test
public void quorumInteropEnabledFailsWithMainnetDefaultNetwork() throws IOException {
final Path genesisFile = createFakeGenesisFile(INVALID_GENESIS_QUORUM_INTEROP_ENABLED_MAINNET);
parseCommand("--genesis-file", genesisFile.toString(), "--min-gas-price", "0");
assertThat(commandErrorOutput.toString(UTF_8))
.contains("isQuorum mode cannot be used on Mainnet.");
}
@Test
public void quorumInteropEnabledFailsWithMainnetChainId() throws IOException {
final Path genesisFile =

@ -495,14 +495,6 @@ public abstract class CommandTestAbstract {
return vertx;
}
@Override
protected void enableGoQuorumCompatibilityMode() {
// We do *not* set the static GoQuorumOptions for test runs as
// these are only allowed to be set once during the program
// runtime.
isGoQuorumCompatibilityMode = true;
}
public CommandSpec getSpec() {
return spec;
}

@ -1,58 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.config;
/**
* Flag to determine whether we are processing in GoQuorum mode. Note that this mode is incompatible
* with MainNet.
*/
public class GoQuorumOptions {
private static final boolean GOQUORUM_COMPATIBILITY_MODE_DEFAULT_VALUE = false;
private static Boolean goQuorumCompatibilityMode;
/**
* Sets go quorum compatibility mode.
*
* @param goQuorumCompatibilityMode the go quorum compatibility mode
*/
public static void setGoQuorumCompatibilityMode(final boolean goQuorumCompatibilityMode) {
if (GoQuorumOptions.goQuorumCompatibilityMode == null) {
GoQuorumOptions.goQuorumCompatibilityMode = goQuorumCompatibilityMode;
} else {
throw new IllegalStateException(
"goQuorumCompatibilityMode can not be changed after having been assigned");
}
}
/**
* Gets go quorum compatibility mode.
*
* @return the go quorum compatibility mode
*/
public static boolean getGoQuorumCompatibilityMode() {
if (goQuorumCompatibilityMode == null) {
// If the quorum mode has never been set, we default it
// here. This allows running individual unit tests that
// query the quorum mode without having to include a
// setGoQuorumCompatibilityMode call in their setup
// procedure. For production use, this case is not
// triggered as we set the quorum mode very early during
// startup.
goQuorumCompatibilityMode = GOQUORUM_COMPATIBILITY_MODE_DEFAULT_VALUE;
}
return goQuorumCompatibilityMode;
}
}

@ -79,11 +79,9 @@ public class CliqueProtocolSchedule {
epochManager,
cliqueConfig.getBlockPeriodSeconds(),
localNodeAddress,
builder,
privacyParameters.getGoQuorumPrivacyParameters().isPresent())),
builder)),
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
evmConfiguration)
.createProtocolSchedule();
}
@ -110,8 +108,7 @@ public class CliqueProtocolSchedule {
final EpochManager epochManager,
final long secondsBetweenBlocks,
final Address localNodeAddress,
final ProtocolSpecBuilder specBuilder,
final boolean goQuorumMode) {
final ProtocolSpecBuilder specBuilder) {
return specBuilder
.blockHeaderValidatorBuilder(
@ -121,7 +118,7 @@ public class CliqueProtocolSchedule {
baseFeeMarket ->
getBlockHeaderValidator(epochManager, secondsBetweenBlocks, baseFeeMarket))
.blockBodyValidatorBuilder(MainnetBlockBodyValidator::new)
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder(goQuorumMode))
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder())
.blockImporterBuilder(MainnetBlockImporter::new)
.difficultyCalculator(new CliqueDifficultyCalculator(localNodeAddress))
.blockReward(Wei.ZERO)

@ -66,9 +66,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
forkSpec ->
specMap.put(
forkSpec.getBlock(),
builder ->
applyBftChanges(
builder, forkSpec.getValue(), config.isQuorum(), bftExtraDataCodec)));
builder -> applyBftChanges(builder, forkSpec.getValue(), bftExtraDataCodec)));
final ProtocolSpecAdapters specAdapters = new ProtocolSpecAdapters(specMap);
@ -80,7 +78,6 @@ public abstract class BaseBftProtocolScheduleBuilder {
specAdapters,
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
evmConfiguration)
.createProtocolSchedule();
return new BftProtocolSchedule(mutableProtocolSchedule);
@ -99,7 +96,6 @@ public abstract class BaseBftProtocolScheduleBuilder {
private ProtocolSpecBuilder applyBftChanges(
final ProtocolSpecBuilder builder,
final BftConfigOptions configOptions,
final boolean goQuorumMode,
final BftExtraDataCodec bftExtraDataCodec) {
if (configOptions.getEpochLength() <= 0) {
throw new IllegalArgumentException("Epoch length in config must be greater than zero");
@ -114,7 +110,7 @@ public abstract class BaseBftProtocolScheduleBuilder {
.ommerHeaderValidatorBuilder(
feeMarket -> createBlockHeaderRuleset(configOptions, feeMarket))
.blockBodyValidatorBuilder(MainnetBlockBodyValidator::new)
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder(goQuorumMode))
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder())
.blockImporterBuilder(MainnetBlockImporter::new)
.difficultyCalculator((time, parent, protocolContext) -> BigInteger.ONE)
.skipZeroBlockRewards(true)

@ -149,7 +149,6 @@ public class CombinedProtocolScheduleFactoryTest {
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
false,
EvmConfiguration.DEFAULT);
return protocolScheduleBuilder.createProtocolSchedule();

@ -1,73 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.ibft;
import org.hyperledger.besu.consensus.common.BlockInterface;
import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.consensus.common.PoaContext;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.ethereum.ConsensusContext;
/** Holds the BFT specific mutable state. */
public class IbftLegacyContext implements PoaContext {
private final ValidatorProvider validatorProvider;
private final EpochManager epochManager;
private final BlockInterface blockInterface;
/**
* Instantiates a new Ibft legacy context.
*
* @param validatorProvider the validator provider
* @param epochManager the epoch manager
* @param blockInterface the block interface
*/
public IbftLegacyContext(
final ValidatorProvider validatorProvider,
final EpochManager epochManager,
final BlockInterface blockInterface) {
this.validatorProvider = validatorProvider;
this.epochManager = epochManager;
this.blockInterface = blockInterface;
}
/**
* Gets validator provider.
*
* @return the validator provider
*/
public ValidatorProvider getValidatorProvider() {
return validatorProvider;
}
/**
* Gets epoch manager.
*
* @return the epoch manager
*/
public EpochManager getEpochManager() {
return epochManager;
}
@Override
public BlockInterface getBlockInterface() {
return blockInterface;
}
@Override
public <C extends ConsensusContext> C as(final Class<C> klass) {
return klass.cast(this);
}
}

@ -16,7 +16,6 @@ package org.hyperledger.besu.consensus.merge;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
@ -24,7 +23,6 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import java.util.List;
import java.util.Optional;
/** The Merge block processor. */
public class MergeBlockProcessor extends MainnetBlockProcessor {
@ -38,7 +36,6 @@ public class MergeBlockProcessor extends MainnetBlockProcessor {
* @param blockReward the block reward
* @param miningBeneficiaryCalculator the mining beneficiary calculator
* @param skipZeroBlockRewards the skip zero block rewards
* @param goQuorumPrivacyParameters the go quorum privacy parameters
* @param protocolSchedule the header based protocol scheduler
*/
public MergeBlockProcessor(
@ -47,7 +44,6 @@ public class MergeBlockProcessor extends MainnetBlockProcessor {
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final HeaderBasedProtocolSchedule protocolSchedule) {
super(
transactionProcessor,
@ -55,7 +51,6 @@ public class MergeBlockProcessor extends MainnetBlockProcessor {
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
goQuorumPrivacyParameters,
protocolSchedule);
this.mergeContext = PostMergeContext.get();
}

@ -71,7 +71,6 @@ public class MergeProtocolSchedule {
specBuilder, config.getChainId())),
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
}
@ -96,7 +95,6 @@ public class MergeProtocolSchedule {
MergeProtocolSchedule::applyMergeSpecificModificationsForShanghai),
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
EvmConfiguration.DEFAULT)
.createTimestampSchedule();
}

@ -1,126 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.types.GoQuorumReceiveResponse;
import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.besu.enclave.types.StoreRawResponse;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import io.vertx.core.Vertx;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
public class GoQuorumEnclaveTest {
private static final byte[] PAYLOAD = Base64.getDecoder().decode("EAAAAAAA");
private static final String MOCK_KEY = "iOCzoGo5kwtZU0J41Z9xnGXHN6ZNukIa9MspvHtu3Jk=";
private static final String KEY =
"tQEmN0d/xXJZs5OMgl8QVBIyYxu1XubAKehsSYbcOjbxai+QJQpEOs6ghrYAZizLtnM4EJdMyVeVrxO3cA9JJA==";
private static GoQuorumEnclave enclave;
private RequestTransmitter vertxTransmitter;
@BeforeEach
public void setUp() {
enclave = createGoQuorumEnclaveWithMockRequestTransmitter();
}
@Test
public void upCheck() {
when(vertxTransmitter.get(
any(), any(), ArgumentMatchers.contains("/upcheck"), any(), anyBoolean()))
.thenReturn("I'm up!");
assertThat(enclave.upCheck()).isTrue();
}
@Test
public void receiveThrowsWhenPayloadDoesNotExist() {
when(vertxTransmitter.get(
any(), any(), ArgumentMatchers.contains("/transaction"), any(), anyBoolean()))
.thenThrow(
new EnclaveClientException(404, "Message with hash " + MOCK_KEY + " was not found"));
assertThatThrownBy(() -> enclave.receive(MOCK_KEY))
.isInstanceOf(EnclaveClientException.class)
.hasMessageContaining("Message with hash " + MOCK_KEY + " was not found");
}
@Test
public void sendAndReceive() {
when(vertxTransmitter.post(any(), any(), any(), any())).thenReturn(new SendResponse(KEY));
when(vertxTransmitter.get(
any(), any(), ArgumentMatchers.contains("/transaction"), any(), anyBoolean()))
.thenReturn(new GoQuorumReceiveResponse(PAYLOAD, 0, null, null));
final List<String> publicKeys = Arrays.asList("/+UuD63zItL1EbjxkKUljMgG8Z1w0AJ8pNOR4iq2yQc=");
final SendResponse sr = enclave.send(PAYLOAD, publicKeys.get(0), publicKeys);
assertThat(sr.getKey()).isEqualTo(KEY);
final GoQuorumReceiveResponse rr = enclave.receive(sr.getKey());
assertThat(rr).isNotNull();
assertThat(rr.getPayload()).isEqualTo(PAYLOAD);
}
@Test
public void sendSignedTransaction() {
when(vertxTransmitter.post(any(), any(), ArgumentMatchers.contains("/sendsignedtx"), any()))
.thenReturn(new SendResponse(KEY));
final List<String> publicKeys = Arrays.asList("/+UuD63zItL1EbjxkKUljMgG8Z1w0AJ8pNOR4iq2yQc=");
final SendResponse sr = enclave.sendSignedTransaction(PAYLOAD, publicKeys);
assertThat(sr.getKey()).isEqualTo(KEY);
}
@Test
public void storeRawTransaction() {
when(vertxTransmitter.post(any(), any(), ArgumentMatchers.contains("/storeraw"), any()))
.thenReturn(new StoreRawResponse(KEY));
final StoreRawResponse sr =
enclave.storeRaw(
"tQEmN0d/xXJZs5OMgl8QVBIyYxu1XubAKehsSYbcOjbxai+QJQpEOs6ghrYAZizLtnM4EJdMyVeVrxO3cA9JJA==");
assertThat(sr.getKey()).isEqualTo(KEY);
}
@Test
public void upcheckReturnsFalseIfNoResponseReceived() throws URISyntaxException {
final Vertx vertx = Vertx.vertx();
final EnclaveFactory factory = new EnclaveFactory(vertx);
assertThat(factory.createGoQuorumEnclave(new URI("http://8.8.8.8:65535")).upCheck()).isFalse();
}
private GoQuorumEnclave createGoQuorumEnclaveWithMockRequestTransmitter() {
vertxTransmitter = mock(RequestTransmitter.class);
return new GoQuorumEnclave(vertxTransmitter);
}
}

@ -85,46 +85,6 @@ public class EnclaveFactory {
return new Enclave(vertxTransmitter);
}
/**
* Create GoQuorum enclave.
*
* @param enclaveUri the enclave uri
* @return the GoQuorum enclave
*/
public GoQuorumEnclave createGoQuorumEnclave(final URI enclaveUri) {
final HttpClientOptions clientOptions = createNonTlsClientOptions(enclaveUri);
final RequestTransmitter vertxTransmitter =
new VertxRequestTransmitter(vertx.createHttpClient(clientOptions));
return new GoQuorumEnclave(vertxTransmitter);
}
/**
* Create GoQuorum enclave.
*
* @param enclaveUri the enclave uri
* @param privacyKeyStoreFile the privacy key store file
* @param privacyKeyStorePasswordFile the privacy key store password file
* @param privacyAllowlistFile the privacy allowlist file
* @return the go quorum enclave
*/
public GoQuorumEnclave createGoQuorumEnclave(
final URI enclaveUri,
final Path privacyKeyStoreFile,
final Path privacyKeyStorePasswordFile,
final Path privacyAllowlistFile) {
final HttpClientOptions clientOptions =
createTlsClientOptions(
enclaveUri, privacyKeyStoreFile, privacyKeyStorePasswordFile, privacyAllowlistFile);
final RequestTransmitter vertxTransmitter =
new VertxRequestTransmitter(vertx.createHttpClient(clientOptions));
return new GoQuorumEnclave(vertxTransmitter);
}
private HttpClientOptions createNonTlsClientOptions(final URI enclaveUri) {
if (enclaveUri.getPort() == -1) {

@ -1,194 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave;
import org.hyperledger.besu.enclave.RequestTransmitter.ResponseBodyHandler;
import org.hyperledger.besu.enclave.types.GoQuorumReceiveResponse;
import org.hyperledger.besu.enclave.types.GoQuorumSendRequest;
import org.hyperledger.besu.enclave.types.GoQuorumSendSignedRequest;
import org.hyperledger.besu.enclave.types.GoQuorumStoreRawRequest;
import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.besu.enclave.types.StoreRawResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/** The GoQuorum enclave. */
public class GoQuorumEnclave {
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final String JSON = "application/json";
private final RequestTransmitter requestTransmitter;
/**
* Instantiates a new GoQuorum enclave.
*
* @param requestTransmitter the request transmitter
*/
public GoQuorumEnclave(final RequestTransmitter requestTransmitter) {
this.requestTransmitter = requestTransmitter;
}
/**
* Up check.
*
* @return the boolean
*/
public boolean upCheck() {
try {
final String upcheckResponse =
requestTransmitter.get(null, null, "/upcheck", this::handleRawResponse, false);
return upcheckResponse.equals("I'm up!");
} catch (final Exception e) {
return false;
}
}
/**
* Send payload.
*
* @param payload the payload
* @param privateFrom the private from
* @param privateFor the private for
* @return the send response
*/
public SendResponse send(
final byte[] payload, final String privateFrom, final List<String> privateFor) {
final GoQuorumSendRequest request = new GoQuorumSendRequest(payload, privateFrom, privateFor);
return post(
JSON,
request,
"/send",
(statusCode, body) -> handleJsonResponse(statusCode, body, SendResponse.class, 201));
}
/**
* Send signed transaction.
*
* @param txLookupId the tx lookup id
* @param privateFor the private for
* @return the send response
*/
public SendResponse sendSignedTransaction(
final byte[] txLookupId, final List<String> privateFor) {
final GoQuorumSendSignedRequest request = new GoQuorumSendSignedRequest(txLookupId, privateFor);
return post(
JSON,
request,
"/sendsignedtx",
(statusCode, body) -> handleJsonResponse(statusCode, body, SendResponse.class, 201));
}
/**
* Store raw payload.
*
* @param payload the payload
* @return the store raw response
*/
public StoreRawResponse storeRaw(final String payload) {
final GoQuorumStoreRawRequest request = new GoQuorumStoreRawRequest(payload);
return post(
JSON,
request,
"/storeraw",
(statusCode, body) -> handleJsonResponse(statusCode, body, StoreRawResponse.class, 200));
}
/**
* Receive GoQuorum response.
*
* @param payloadKey the payload key
* @return the go quorum receive response
*/
public GoQuorumReceiveResponse receive(final String payloadKey) {
return get(
JSON,
"/transaction/" + URLEncoder.encode(payloadKey, StandardCharsets.UTF_8),
(statusCode, body) ->
handleJsonResponse(statusCode, body, GoQuorumReceiveResponse.class, 200));
}
private <T> T post(
final String mediaType,
final Object content,
final String endpoint,
final ResponseBodyHandler<T> responseBodyHandler) {
final String bodyText;
try {
bodyText = objectMapper.writeValueAsString(content);
} catch (final JsonProcessingException e) {
throw new EnclaveClientException(400, "Unable to serialize request.");
}
return requestTransmitter.post(mediaType, bodyText, endpoint, responseBodyHandler);
}
private <T> T get(
final String mediaType,
final String endpoint,
final ResponseBodyHandler<T> responseBodyHandler) {
final T t = requestTransmitter.get(mediaType, null, endpoint, responseBodyHandler, true);
return t;
}
private <T> T handleJsonResponse(
final int statusCode,
final byte[] body,
final Class<T> responseType,
final int expectedStatusCode) {
if (isSuccess(statusCode, expectedStatusCode)) {
return parseResponse(statusCode, body, responseType);
} else if (clientError(statusCode)) {
final String utf8EncodedBody = new String(body, StandardCharsets.UTF_8);
throw new EnclaveClientException(statusCode, utf8EncodedBody);
} else {
final String utf8EncodedBody = new String(body, StandardCharsets.UTF_8);
throw new EnclaveServerException(statusCode, utf8EncodedBody);
}
}
private <T> T parseResponse(
final int statusCode, final byte[] body, final Class<T> responseType) {
try {
return objectMapper.readValue(body, responseType);
} catch (final IOException e) {
final String utf8EncodedBody = new String(body, StandardCharsets.UTF_8);
throw new EnclaveClientException(statusCode, utf8EncodedBody);
}
}
private boolean clientError(final int statusCode) {
return statusCode >= 400 && statusCode < 500;
}
private boolean isSuccess(final int statusCode, final int expectedStatusCode) {
return statusCode == expectedStatusCode;
}
private String handleRawResponse(final int statusCode, final byte[] body) {
final String bodyText = new String(body, StandardCharsets.UTF_8);
if (isSuccess(statusCode, 200)) {
return bodyText;
}
throw new EnclaveClientException(
statusCode, String.format("Request failed with %d; body={%s}", statusCode, bodyText));
}
}

@ -1,84 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave.types;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/** The GoQuorum receive response. */
public class GoQuorumReceiveResponse {
private final byte[] payload;
private final int privacyFlag;
private final String affectedContractTransactions[];
private final String execHash;
/**
* Instantiates a new GoQuorum receive response.
*
* @param payload the payload
* @param privacyFlag the privacy flag
* @param affectedContractTransactions the affected contract transactions
* @param execHash the exec hash
*/
@JsonCreator
public GoQuorumReceiveResponse(
@JsonProperty(value = "payload") final byte[] payload,
@JsonProperty(value = "privacyFlag") final int privacyFlag,
@JsonProperty(value = "affectedContractTransactions")
final String affectedContractTransactions[],
@JsonProperty(value = "execHash") final String execHash) {
this.payload = payload;
this.privacyFlag = privacyFlag;
this.affectedContractTransactions = affectedContractTransactions;
this.execHash = execHash;
}
/**
* Get payload.
*
* @return the byte [ ]
*/
public byte[] getPayload() {
return payload;
}
/**
* Gets privacy flag.
*
* @return the privacy flag
*/
public int getPrivacyFlag() {
return privacyFlag;
}
/**
* Get affected contract transactions.
*
* @return the string [ ]
*/
public String[] getAffectedContractTransactions() {
return affectedContractTransactions;
}
/**
* Gets exec hash.
*
* @return the exec hash
*/
public String getExecHash() {
return execHash;
}
}

@ -1,71 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave.types;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
/** The GoQuorum send request. */
@JsonPropertyOrder({"payload", "from", "to"})
public class GoQuorumSendRequest {
private final byte[] payload;
private final String from;
private final List<String> to;
/**
* Instantiates a new Go quorum send request.
*
* @param payload the payload
* @param from the from
* @param to the to
*/
public GoQuorumSendRequest(
@JsonProperty(value = "payload") final byte[] payload,
@JsonProperty(value = "from") final String from,
@JsonProperty(value = "to") final List<String> to) {
this.payload = payload;
this.from = from;
this.to = to;
}
/**
* Get payload byte [ ].
*
* @return the byte [ ]
*/
public byte[] getPayload() {
return payload;
}
/**
* Gets from.
*
* @return the from
*/
public String getFrom() {
return from;
}
/**
* Gets to.
*
* @return the to
*/
public List<String> getTo() {
return to;
}
}

@ -1,58 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave.types;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
/** The GoQuorum send signed request. */
@JsonPropertyOrder({"hash", "to"})
public class GoQuorumSendSignedRequest {
private final byte[] hash;
private final List<String> to;
/**
* Instantiates a new GoQuorum send signed request.
*
* @param hash the hash
* @param privateFor the private for
*/
public GoQuorumSendSignedRequest(
@JsonProperty(value = "hash") final byte[] hash,
@JsonProperty(value = "to") final List<String> privateFor) {
this.hash = hash;
this.to = privateFor;
}
/**
* Get hash byte [ ].
*
* @return the byte [ ]
*/
public byte[] getHash() {
return hash;
}
/**
* Gets to.
*
* @return the to
*/
public List<String> getTo() {
return to;
}
}

@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.enclave.types;
import com.fasterxml.jackson.annotation.JsonProperty;
/** The type Go quorum store raw request. */
public class GoQuorumStoreRawRequest {
private final String payload;
/**
* Instantiates a new Go quorum store raw request.
*
* @param payload the payload
*/
public GoQuorumStoreRawRequest(@JsonProperty(value = "payload") final String payload) {
this.payload = payload;
}
/**
* Gets payload.
*
* @return the payload
*/
public String getPayload() {
return payload;
}
}

@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.AccountAdapter;
import org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.EmptyAccountAdapter;
import org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter.LogAdapter;
@ -33,7 +32,6 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.LogsQuery;
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.core.Transaction;
@ -63,21 +61,10 @@ import graphql.GraphQLContext;
import graphql.schema.DataFetcher;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GraphQLDataFetchers {
private static final Logger LOG = LoggerFactory.getLogger(GraphQLDataFetchers.class);
private final Integer highestEthVersion;
private Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters = Optional.empty();
public GraphQLDataFetchers(
final Set<Capability> supportedCapabilities,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters) {
this(supportedCapabilities);
this.goQuorumPrivacyParameters = goQuorumPrivacyParameters;
}
public GraphQLDataFetchers(final Set<Capability> supportedCapabilities) {
final OptionalInt version =
@ -312,46 +299,6 @@ public class GraphQLDataFetchers {
private TransactionAdapter getTransactionAdapter(
final TransactionWithMetadata transactionWithMetadata) {
final Transaction transaction = transactionWithMetadata.getTransaction();
final boolean isGoQuorumCompatbilityMode = goQuorumPrivacyParameters.isPresent();
final boolean isGoQuorumPrivateTransaction =
isGoQuorumCompatbilityMode
&& transaction.isGoQuorumPrivateTransaction(isGoQuorumCompatbilityMode);
return isGoQuorumPrivateTransaction
? updatePrivatePayload(transaction)
: new TransactionAdapter(transactionWithMetadata);
}
private TransactionAdapter updatePrivatePayload(final Transaction transaction) {
final GoQuorumEnclave enclave = goQuorumPrivacyParameters.get().enclave();
Bytes enclavePayload;
try {
// Retrieve the payload from the enclave
enclavePayload =
Bytes.wrap(enclave.receive(transaction.getPayload().toBase64String()).getPayload());
} catch (final Exception ex) {
LOG.debug("An error occurred while retrieving the GoQuorum transaction payload: ", ex);
enclavePayload = Bytes.EMPTY;
}
// Return a new transaction containing the retrieved payload
return new TransactionAdapter(
new TransactionWithMetadata(
new Transaction(
transaction.getNonce(),
transaction.getGasPrice(),
transaction.getMaxPriorityFeePerGas(),
transaction.getMaxFeePerGas(),
transaction.getMaxFeePerDataGas(),
transaction.getGasLimit(),
transaction.getTo(),
transaction.getValue(),
transaction.getSignature(),
enclavePayload,
transaction.getSender(),
transaction.getChainId(),
Optional.ofNullable(transaction.getV()),
transaction.getVersionedHashes())));
return new TransactionAdapter(transactionWithMetadata);
}
}

@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
@ -209,20 +208,6 @@ public class TransactionAdapter extends AdapterBase {
return results;
}
public boolean getIsPrivate() {
return transactionWithMetadata
.getTransaction()
.isGoQuorumPrivateTransaction(GoQuorumOptions.getGoQuorumCompatibilityMode());
}
public Optional<Bytes> getPrivateInputData() {
final Transaction transaction = transactionWithMetadata.getTransaction();
if (transaction.isGoQuorumPrivateTransaction(GoQuorumOptions.getGoQuorumCompatibilityMode())) {
return Optional.ofNullable(transaction.getPayload());
}
return Optional.of(Bytes.EMPTY);
}
public List<AccessListEntryAdapter> getAccessList() {
return transactionWithMetadata
.getTransaction()

@ -59,10 +59,6 @@ public class JsonRpcErrorConverter {
return JsonRpcError.ETH_SEND_TX_ALREADY_KNOWN;
case TRANSACTION_REPLACEMENT_UNDERPRICED:
return JsonRpcError.ETH_SEND_TX_REPLACEMENT_UNDERPRICED;
case GAS_PRICE_MUST_BE_ZERO:
return JsonRpcError.GAS_PRICE_MUST_BE_ZERO;
case ETHER_VALUE_NOT_SUPPORTED:
return JsonRpcError.ETHER_VALUE_NOT_SUPPORTED;
case NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER:
return JsonRpcError.NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER;
case LOWER_NONCE_INVALID_TRANSACTION_EXISTS:

@ -32,7 +32,6 @@ public enum RpcApis {
TXPOOL,
TRACE,
PLUGINS,
GOQUORUM,
CLIQUE,
IBFT,
ENGINE,

@ -59,8 +59,6 @@ public enum RpcMethod {
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1("engine_getPayloadBodiesByRangeV1"),
ENGINE_EXCHANGE_CAPABILITIES("engine_exchangeCapabilities"),
GOQUORUM_ETH_GET_QUORUM_PAYLOAD("eth_getQuorumPayload"),
GOQUORUM_STORE_RAW("goquorum_storeRaw"),
PRIV_CALL("priv_call"),
PRIV_GET_PRIVATE_TRANSACTION("priv_getPrivateTransaction"),
PRIV_GET_TRANSACTION_COUNT("priv_getTransactionCount"),

@ -14,39 +14,25 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import static org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStateUtil.getPrivateWorldStateAtBlock;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameterOrBlockHash;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.evm.account.Account;
import java.util.Optional;
import java.util.function.Supplier;
import org.apache.tuweni.bytes.Bytes;
public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod {
final Optional<PrivacyParameters> privacyParameters;
public EthGetCode(
final BlockchainQueries blockchainQueries,
final Optional<PrivacyParameters> privacyParameters) {
public EthGetCode(final BlockchainQueries blockchainQueries) {
super(blockchainQueries);
this.privacyParameters = privacyParameters;
}
public EthGetCode(
final Supplier<BlockchainQueries> blockchainQueries,
final Optional<PrivacyParameters> privacyParameters) {
public EthGetCode(final Supplier<BlockchainQueries> blockchainQueries) {
super(blockchainQueries);
this.privacyParameters = privacyParameters;
}
@Override
@ -63,21 +49,6 @@ public class EthGetCode extends AbstractBlockParameterOrBlockHashMethod {
@Override
protected String resultByBlockHash(final JsonRpcRequestContext request, final Hash blockHash) {
final Address address = request.getRequiredParameter(0, Address.class);
if (privacyParameters.isPresent()
&& privacyParameters.get().getGoQuorumPrivacyParameters().isPresent()) {
// get from private state if we can
final Optional<BlockHeader> blockHeader =
blockchainQueries.get().getBlockHeaderByHash(blockHash);
if (blockHeader.isPresent()) {
final MutableWorldState privateState =
getPrivateWorldStateAtBlock(
privacyParameters.get().getGoQuorumPrivacyParameters(), blockHeader.get());
final Account privAccount = privateState.get(address);
if (privAccount != null) {
return privAccount.getCode().toHexString();
}
}
}
return getBlockchainQueries().getCode(address, blockHash).map(Bytes::toString).orElse(null);
}
}

@ -17,7 +17,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyUserUtil.privacyUserId;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.util.InvalidConfigurationException;
import java.util.Optional;
@ -29,9 +28,7 @@ public interface PrivacyIdProvider {
String getPrivacyUserId(Optional<User> user);
static PrivacyIdProvider build(final PrivacyParameters privacyParameters) {
if (privacyParameters.getGoQuorumPrivacyParameters().isPresent()) {
return goQuorumPrivacyUserIdProvider(privacyParameters);
} else if (privacyParameters.isMultiTenancyEnabled()) {
if (privacyParameters.isMultiTenancyEnabled()) {
return multiTenancyPrivacyUserIdProvider();
}
return defaultPrivacyUserIdProvider(privacyParameters);
@ -48,14 +45,4 @@ public interface PrivacyIdProvider {
final PrivacyParameters privacyParameters) {
return user -> privacyParameters.getPrivacyUserId();
}
private static PrivacyIdProvider goQuorumPrivacyUserIdProvider(
final PrivacyParameters privacyParameters) {
return user ->
privacyParameters
.getGoQuorumPrivacyParameters()
.orElseThrow(
() -> new InvalidConfigurationException("GoQuorumPrivacyParameters not set"))
.enclaveKey();
}
}

@ -1,79 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import org.hyperledger.besu.enclave.EnclaveClientException;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.enclave.types.GoQuorumReceiveResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoQuorumEthGetQuorumPayload implements JsonRpcMethod {
private static final Logger LOG = LoggerFactory.getLogger(GoQuorumEthGetQuorumPayload.class);
private final GoQuorumEnclave enclave;
public GoQuorumEthGetQuorumPayload(final GoQuorumEnclave enclave) {
this.enclave = enclave;
}
@Override
public String getName() {
return RpcMethod.GOQUORUM_ETH_GET_QUORUM_PAYLOAD.getMethodName();
}
@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
final String key = requestContext.getRequiredParameter(0, String.class);
final Bytes bytes;
try {
bytes = Bytes.fromHexString(key);
} catch (final IllegalArgumentException e) {
LOG.debug("Enclave key contains invalid hex character {}", key);
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.INVALID_PARAMS);
}
if (bytes.size() != 64) {
LOG.debug("Enclave key expected length 64, but length is {}", bytes.size());
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.INVALID_PARAMS);
}
try {
final GoQuorumReceiveResponse receive = enclave.receive(bytes.toBase64String());
return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(), Bytes.wrap(receive.getPayload()).toHexString());
} catch (final EnclaveClientException ex) {
if (ex.getStatusCode() == 404) {
return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(), Bytes.EMPTY.toHexString());
} else {
LOG.debug("Error retrieving enclave payload: ", ex);
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.INTERNAL_ERROR);
}
}
}
}

@ -1,161 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter.convertEnclaveInvalidReason;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter.convertTransactionInvalidReason;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.DECODE_ERROR;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.eea.JsonRpcErrorResponseException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.privacy.GoQuorumSendRawTxArgs;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import java.math.BigInteger;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoQuorumSendRawPrivateTransaction implements JsonRpcMethod {
private static final Logger LOG =
LoggerFactory.getLogger(GoQuorumSendRawPrivateTransaction.class);
final TransactionPool transactionPool;
private final PrivacyIdProvider privacyIdProvider;
private final GoQuorumEnclave enclave;
private final boolean goQuorumCompatibilityMode;
public GoQuorumSendRawPrivateTransaction(
final GoQuorumEnclave enclave,
final TransactionPool transactionPool,
final PrivacyIdProvider privacyIdProvider) {
this(
enclave,
transactionPool,
privacyIdProvider,
GoQuorumOptions.getGoQuorumCompatibilityMode());
}
public GoQuorumSendRawPrivateTransaction(
final GoQuorumEnclave enclave,
final TransactionPool transactionPool,
final PrivacyIdProvider privacyIdProvider,
final boolean goQuorumCompatibilityMode) {
this.enclave = enclave;
this.transactionPool = transactionPool;
this.privacyIdProvider = privacyIdProvider;
this.goQuorumCompatibilityMode = goQuorumCompatibilityMode;
}
@Override
public String getName() {
return RpcMethod.ETH_SEND_RAW_PRIVATE_TRANSACTION.getMethodName();
}
@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
final Object id = requestContext.getRequest().getId();
final String rawPrivateTransaction = requestContext.getRequiredParameter(0, String.class);
final GoQuorumSendRawTxArgs rawTxArgs =
requestContext.getRequiredParameter(1, GoQuorumSendRawTxArgs.class);
try {
final Transaction transaction =
TransactionDecoder.decodeForWire(
RLP.input(Bytes.fromHexString(rawPrivateTransaction)), goQuorumCompatibilityMode);
checkAndHandlePrivateTransaction(transaction, rawTxArgs, requestContext);
return transactionPool
.addLocalTransaction(transaction)
.either(
() -> new JsonRpcSuccessResponse(id, transaction.getHash().toString()),
errorReason -> getJsonRpcErrorResponse(id, errorReason));
} catch (final JsonRpcErrorResponseException e) {
return new JsonRpcErrorResponse(id, e.getJsonRpcError());
} catch (final IllegalArgumentException | RLPException e) {
LOG.error("Unable to decode private transaction for send", e);
return new JsonRpcErrorResponse(id, DECODE_ERROR);
} catch (final Exception e) {
LOG.error("Unexpected error", e);
return new JsonRpcErrorResponse(id, convertEnclaveInvalidReason(e.getMessage()));
}
}
private void checkAndHandlePrivateTransaction(
final Transaction transaction,
final GoQuorumSendRawTxArgs rawTxArgs,
final JsonRpcRequestContext requestContext) {
// rawTxArgs cannot be null as the call to getRequiredParameter would have failed if it was not
// available
if (rawTxArgs.getPrivateFor() == null) {
LOG.error(JsonRpcError.GOQUORUM_NO_PRIVATE_FOR.getMessage());
throw new JsonRpcErrorResponseException(JsonRpcError.GOQUORUM_NO_PRIVATE_FOR);
}
if (rawTxArgs.getPrivacyFlag() != 0) {
LOG.error(JsonRpcError.GOQUORUM_ONLY_STANDARD_MODE_SUPPORTED.getMessage());
throw new JsonRpcErrorResponseException(JsonRpcError.GOQUORUM_ONLY_STANDARD_MODE_SUPPORTED);
}
if (rawTxArgs.getPrivateFrom() != null) {
final String privateFrom = rawTxArgs.getPrivateFrom();
final String privacyUserId = privacyIdProvider.getPrivacyUserId(requestContext.getUser());
if (!privateFrom.equals(privacyUserId)) {
LOG.error(JsonRpcError.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY.getMessage());
throw new JsonRpcErrorResponseException(
JsonRpcError.PRIVATE_FROM_DOES_NOT_MATCH_ENCLAVE_PUBLIC_KEY);
}
}
if (!transaction.getV().equals(BigInteger.valueOf(37))
&& !transaction.getV().equals(BigInteger.valueOf(38))) {
LOG.error(JsonRpcError.GOQUORUM_V_VALUE.getMessage());
throw new JsonRpcErrorResponseException(JsonRpcError.GOQUORUM_V_VALUE);
}
final Bytes txId = transaction.getPayload();
if (txId == null || txId.isEmpty()) {
throw new JsonRpcErrorResponseException(JsonRpcError.GOQUORUM_LOOKUP_ID_NOT_AVAILABLE);
}
enclave.sendSignedTransaction(txId.toArray(), rawTxArgs.getPrivateFor());
}
JsonRpcErrorResponse getJsonRpcErrorResponse(
final Object id, final TransactionInvalidReason errorReason) {
if (errorReason.equals(TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT)) {
return new JsonRpcErrorResponse(id, JsonRpcError.PMT_FAILED_INTRINSIC_GAS_EXCEEDS_LIMIT);
}
return new JsonRpcErrorResponse(id, convertTransactionInvalidReason(errorReason));
}
}

@ -1,75 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter.convertEnclaveInvalidReason;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.DECODE_ERROR;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.enclave.types.StoreRawResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import java.util.Base64;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoQuorumStoreRawPrivateTransaction implements JsonRpcMethod {
private static final Logger LOG =
LoggerFactory.getLogger(GoQuorumStoreRawPrivateTransaction.class);
private final GoQuorumEnclave enclave;
public GoQuorumStoreRawPrivateTransaction(final GoQuorumEnclave enclave) {
this.enclave = enclave;
}
@Override
public String getName() {
return RpcMethod.GOQUORUM_STORE_RAW.getMethodName();
}
@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
final Object id = requestContext.getRequest().getId();
final String payload = requestContext.getRequiredParameter(0, String.class);
try {
LOG.debug("sending payload to GoQuorum enclave" + payload);
final StoreRawResponse storeRawResponse =
enclave.storeRaw(
Base64.getEncoder().encodeToString(Bytes.fromHexString(payload).toArray()));
final String enclaveLookupId = storeRawResponse.getKey();
LOG.debug("retrieved lookupId from GoQuorum enclave " + enclaveLookupId);
return new JsonRpcSuccessResponse(id, hexEncodeEnclaveKey(enclaveLookupId));
} catch (final IllegalArgumentException | RLPException e) {
LOG.error("Unable to decode private transaction for store", e);
return new JsonRpcErrorResponse(id, DECODE_ERROR);
} catch (final Exception e) {
return new JsonRpcErrorResponse(id, convertEnclaveInvalidReason(e.getMessage()));
}
}
private String hexEncodeEnclaveKey(final String enclaveKey) {
return Bytes.wrap(Base64.getDecoder().decode(enclaveKey)).toHexString();
}
}

@ -69,7 +69,6 @@ public enum JsonRpcError {
REPLAY_PROTECTED_SIGNATURE_REQUIRED(-32000, "ChainId is required"),
TX_FEECAP_EXCEEDED(-32000, "Transaction fee cap exceeded"),
REVERT_ERROR(-32000, "Execution reverted"),
GAS_PRICE_MUST_BE_ZERO(-3200, "gasPrice must be set to zero on a GoQuorum compatible network"),
TRANSACTION_NOT_FOUND(-32000, "Transaction not found"),
MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS(
-32000, "Max priority fee per gas exceeds max fee per gas"),
@ -144,17 +143,8 @@ public enum JsonRpcError {
CREATE_PRIVACY_GROUP_ERROR(-50100, "Error creating privacy group"),
DECODE_ERROR(-50100, "Unable to decode the private signed raw transaction"),
DELETE_PRIVACY_GROUP_ERROR(-50100, "Error deleting privacy group"),
ETHER_VALUE_NOT_SUPPORTED(-50100, "ether value is not supported for private transactions"),
FIND_PRIVACY_GROUP_ERROR(-50100, "Error finding privacy group"),
FIND_FLEXIBLE_PRIVACY_GROUP_ERROR(-50100, "Error finding flexible privacy group"),
GOQUORUM_NO_PRIVATE_FOR(
-50100, "No privateFor specified in rawTxArgs for GoQuorum raw private transaction."),
GOQUORUM_ONLY_STANDARD_MODE_SUPPORTED(
-50100,
"Invalid private transaction mode defined in rawTxArgs for GoQuorum raw private transaction."),
GOQUORUM_LOOKUP_ID_NOT_AVAILABLE(
-50100, "No lookup id specified in GoQuorum raw private transaction."),
GOQUORUM_V_VALUE(-50100, "Signature v value not 37 or 38 for GoQuorum private transaction."),
GET_PRIVATE_TRANSACTION_NONCE_ERROR(-50100, "Unable to determine nonce for account in group."),
OFFCHAIN_PRIVACY_GROUP_DOES_NOT_EXIST(-50100, "Offchain Privacy group does not exist."),
FLEXIBLE_PRIVACY_GROUP_DOES_NOT_EXIST(-50100, "Flexible Privacy group does not exist."),

@ -64,7 +64,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Synchronizer;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -86,7 +85,6 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
private final TransactionPool transactionPool;
private final MiningCoordinator miningCoordinator;
private final Set<Capability> supportedCapabilities;
private final PrivacyParameters privacyParameters;
private final Optional<Long> maxLogRange;
public EthJsonRpcMethods(
@ -97,7 +95,6 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
final TransactionPool transactionPool,
final MiningCoordinator miningCoordinator,
final Set<Capability> supportedCapabilities,
final PrivacyParameters privacyParameters,
final Optional<Long> maxLogRange) {
this.blockchainQueries = blockchainQueries;
this.synchronizer = synchronizer;
@ -106,7 +103,6 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
this.transactionPool = transactionPool;
this.miningCoordinator = miningCoordinator;
this.supportedCapabilities = supportedCapabilities;
this.privacyParameters = privacyParameters;
this.maxLogRange = maxLogRange;
}
@ -130,10 +126,9 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)),
protocolSchedule)),
new EthFeeHistory(protocolSchedule, blockchainQueries.getBlockchain()),
new EthGetCode(blockchainQueries, Optional.of(privacyParameters)),
new EthGetCode(blockchainQueries),
new EthGetLogs(blockchainQueries, maxLogRange),
new EthGetProof(blockchainQueries),
new EthGetUncleCountByBlockHash(blockchainQueries),
@ -160,15 +155,13 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)),
protocolSchedule)),
new EthCreateAccessList(
blockchainQueries,
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)),
protocolSchedule)),
new EthMining(miningCoordinator),
new EthCoinbase(miningCoordinator),
new EthProtocolVersion(supportedCapabilities),

@ -1,71 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.GoQuorumEthGetQuorumPayload;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.GoQuorumSendRawPrivateTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.GoQuorumStoreRawPrivateTransaction;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import org.hyperledger.besu.plugin.services.privacy.PrivateMarkerTransactionFactory;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
public class GoQuorumJsonRpcPrivacyMethods extends PrivacyApiGroupJsonRpcMethods {
private final Optional<GoQuorumPrivacyParameters> goQuorumParameters;
public GoQuorumJsonRpcPrivacyMethods(
final BlockchainQueries blockchainQueries,
final ProtocolSchedule protocolSchedule,
final TransactionPool transactionPool,
final PrivacyParameters privacyParameters) {
super(blockchainQueries, protocolSchedule, transactionPool, privacyParameters);
this.goQuorumParameters = privacyParameters.getGoQuorumPrivacyParameters();
}
@Override
protected Map<String, JsonRpcMethod> create(
final PrivacyController privacyController,
final PrivacyIdProvider enclavePublicKeyProvider,
final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) {
if (goQuorumParameters.isPresent()) {
final GoQuorumEnclave enclave = goQuorumParameters.get().enclave();
return mapOf(
new GoQuorumSendRawPrivateTransaction(
enclave, getTransactionPool(), enclavePublicKeyProvider),
new GoQuorumStoreRawPrivateTransaction(enclave),
new GoQuorumEthGetQuorumPayload(enclave));
} else {
return Collections.emptyMap();
}
}
@Override
protected String getApiGroup() {
return RpcApis.GOQUORUM.name();
}
}

@ -112,8 +112,6 @@ public class JsonRpcMethodsFactory {
protocolContext,
ethPeers,
consensusEngineServer),
new GoQuorumJsonRpcPrivacyMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new EthJsonRpcMethods(
blockchainQueries,
synchronizer,
@ -122,7 +120,6 @@ public class JsonRpcMethodsFactory {
transactionPool,
miningCoordinator,
supportedCapabilities,
privacyParameters,
maxLogRange),
new NetJsonRpcMethods(
p2pNetwork,
@ -141,7 +138,7 @@ public class JsonRpcMethodsFactory {
new PrivxJsonRpcMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters),
new Web3JsonRpcMethods(clientVersion),
new TraceJsonRpcMethods(blockchainQueries, protocolSchedule, privacyParameters),
new TraceJsonRpcMethods(blockchainQueries, protocolSchedule),
new TxPoolJsonRpcMethods(transactionPool),
new PluginsJsonRpcMethods(namedPlugins));

@ -169,9 +169,7 @@ public abstract class PrivacyApiGroupJsonRpcMethods extends ApiGroupJsonRpcMetho
private JsonRpcMethod createPrivacyMethod(
final PrivacyParameters privacyParameters, final JsonRpcMethod rpcMethod) {
final String methodName = rpcMethod.getName();
if (methodName.equals(RpcMethod.ETH_SEND_RAW_PRIVATE_TRANSACTION.getMethodName())
|| methodName.equals(RpcMethod.GOQUORUM_STORE_RAW.getMethodName())
|| methodName.equals(RpcMethod.GOQUORUM_ETH_GET_QUORUM_PAYLOAD.getMethodName())) {
if (methodName.equals(RpcMethod.ETH_SEND_RAW_PRIVATE_TRANSACTION.getMethodName())) {
return rpcMethod;
} else if (privacyParameters.isEnabled() && privacyParameters.isMultiTenancyEnabled()) {
return new MultiTenancyRpcMethodDecorator(rpcMethod);

@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.TraceTransacti
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockReplay;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.BlockTracer;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
@ -37,15 +36,11 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
private final BlockchainQueries blockchainQueries;
private final ProtocolSchedule protocolSchedule;
private final PrivacyParameters privacyParameters;
TraceJsonRpcMethods(
final BlockchainQueries blockchainQueries,
final ProtocolSchedule protocolSchedule,
final PrivacyParameters privacyParameters) {
final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule) {
this.blockchainQueries = blockchainQueries;
this.protocolSchedule = protocolSchedule;
this.privacyParameters = privacyParameters;
}
@Override
@ -70,23 +65,20 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)),
protocolSchedule)),
new TraceCallMany(
blockchainQueries,
protocolSchedule,
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)),
protocolSchedule)),
new TraceRawTransaction(
protocolSchedule,
blockchainQueries,
new TransactionSimulator(
blockchainQueries.getBlockchain(),
blockchainQueries.getWorldStateArchive(),
protocolSchedule,
privacyParameters)));
protocolSchedule)));
}
}

@ -724,7 +724,7 @@ public class BlockchainQueries {
// handles the case when fromBlockNumber is past chain head.
.takeWhile(Optional::isPresent)
.map(Optional::get)
.filter(header -> query.couldMatch(header.getLogsBloom(true)))
.filter(header -> query.couldMatch(header.getLogsBloom()))
.flatMap(header -> matchingLogs(header.getHash(), query, isQueryAlive).stream())
.collect(Collectors.toList());
}

@ -207,7 +207,7 @@ public class TransactionLogBloomCacher {
throw new InvalidCacheException();
}
writer.seek(offset);
writer.write(ensureBloomBitsAreCorrectLength(blockHeader.getLogsBloom(true).toArray()));
writer.write(ensureBloomBitsAreCorrectLength(blockHeader.getLogsBloom().toArray()));
// remove invalid logs when there was a reorg
final long validCacheSize = offset + BLOOM_BITS_LENGTH;
@ -309,7 +309,7 @@ public class TransactionLogBloomCacher {
private void fillCacheFileWithBlock(final BlockHeader blockHeader, final OutputStream fos)
throws IOException {
fos.write(ensureBloomBitsAreCorrectLength(blockHeader.getLogsBloom(true).toArray()));
fos.write(ensureBloomBitsAreCorrectLength(blockHeader.getLogsBloom().toArray()));
}
private byte[] ensureBloomBitsAreCorrectLength(final byte[] logs) {

@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.util;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcRequestException;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
@ -28,8 +27,7 @@ public class DomainObjectDecodeUtils {
throws InvalidJsonRpcRequestException {
try {
Bytes txnBytes = Bytes.fromHexString(rawTransaction);
final boolean isGoQuorumCompatibilityMode = GoQuorumOptions.getGoQuorumCompatibilityMode();
return TransactionDecoder.decodeOpaqueBytes(txnBytes, isGoQuorumCompatibilityMode);
return TransactionDecoder.decodeOpaqueBytes(txnBytes);
} catch (final IllegalArgumentException e) {
throw new InvalidJsonRpcRequestException("Invalid raw transaction hex", e);
} catch (final RLPException r) {

@ -73,8 +73,7 @@ public class JsonRpcErrorConverterTest {
{
TransactionInvalidReason.TRANSACTION_REPLACEMENT_UNDERPRICED,
JsonRpcError.ETH_SEND_TX_REPLACEMENT_UNDERPRICED
},
{TransactionInvalidReason.GAS_PRICE_MUST_BE_ZERO, JsonRpcError.GAS_PRICE_MUST_BE_ZERO}
}
});
}

@ -176,12 +176,6 @@ public class EthSendRawTransactionTest {
TransactionInvalidReason.TX_FEECAP_EXCEEDED, JsonRpcError.TX_FEECAP_EXCEEDED);
}
@Test
public void transactionWithNonZeroGasWithGoQuorumCompatibilityIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.GAS_PRICE_MUST_BE_ZERO, JsonRpcError.GAS_PRICE_MUST_BE_ZERO);
}
private void verifyErrorForInvalidTransaction(
final TransactionInvalidReason transactionInvalidReason, final JsonRpcError expectedError) {
when(transactionPool.addLocalTransaction(any(Transaction.class)))

@ -1,150 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.goquorum;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.EnclaveClientException;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.enclave.types.GoQuorumReceiveResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.GoQuorumEthGetQuorumPayload;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("DirectInvocationOnMock")
public class GoQuorumEthGetQuorumPayloadTest {
@Mock GoQuorumEthGetQuorumPayload method;
@Mock GoQuorumEnclave enclave;
@Before
public void before() {
method = new GoQuorumEthGetQuorumPayload(enclave);
}
@Test
public void correctRequest() {
final String hexString = Bytes.wrap(new byte[64]).toHexString();
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {hexString}));
when(enclave.receive(any()))
.thenReturn(new GoQuorumReceiveResponse(new byte[10], 0, null, null));
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
assertThat(((JsonRpcSuccessResponse) response).getResult().toString())
.isEqualTo("0x00000000000000000000");
}
@Test
public void requestIsMissingParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {}));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void requestHasNullObjectParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_getQuorumPayload", null));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void requestHasNullArrayParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {null}));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void requestHasShortHex() {
final String hexString = Bytes.wrap(new byte[63]).toHexString();
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {hexString}));
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
assertThat(response.toString()).contains("INVALID_PARAMS");
}
@Test
public void requestHasLongHex() {
final String hexString = Bytes.wrap(new byte[65]).toHexString();
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {hexString}));
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
assertThat(response.toString()).contains("INVALID_PARAMS");
}
@Test
public void requestNonHexString() {
final String hexString = Bytes.wrap(new byte[63]).toHexString() + "f";
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {hexString}));
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcErrorResponse.class);
assertThat(response.toString()).contains("INVALID_PARAMS");
}
@Test
public void enclave404ReturnsEmptyBytesString() {
final String hexString = Bytes.wrap(new byte[64]).toHexString();
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_getQuorumPayload", new String[] {hexString}));
when(enclave.receive(any())).thenThrow(new EnclaveClientException(404, null));
final JsonRpcResponse response = method.response(request);
assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class);
assertThat(((JsonRpcSuccessResponse) response).getResult())
.isEqualTo(Bytes.EMPTY.toHexString());
}
}

@ -1,298 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.goquorum;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.GoQuorumSendRawPrivateTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.privacy.GoQuorumSendRawTxArgs;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.plugin.data.Restriction;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("DirectInvocationOnMock")
public class GoQuorumSendRawPrivateTransactionTest {
static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
static final String INVALID_TRANSACTION_RLP = invalidGQPrivateTransactionRlp();
static final String ENCLAVE_PUBLIC_KEY = "S28yYlZxRCtuTmxOWUw1RUU3eTNJZE9udmlmdGppaXo=";
final PrivacyIdProvider privacyIdProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Mock GoQuorumSendRawPrivateTransaction method;
@Mock TransactionPool transactionPool;
@Mock GoQuorumEnclave enclave;
private static final String RAW_TRANSACTION_STRING = "someString";
private static final String RAW_TRANSACTION = createValidTransactionRLP();
private static final GoQuorumSendRawTxArgs GO_QUORUM_SEND_RAW_TX_ARGS =
new GoQuorumSendRawTxArgs(
ENCLAVE_PUBLIC_KEY, Collections.singletonList(ENCLAVE_PUBLIC_KEY), 0);
@Before
public void before() {
boolean goQuorumCompatibilityMode = true;
method =
new GoQuorumSendRawPrivateTransaction(
enclave, transactionPool, privacyIdProvider, goQuorumCompatibilityMode);
}
@Test
public void requestIsMissingParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "eth_sendRawPrivateTransaction", new String[] {}));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
final JsonRpcRequestContext request2 =
new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0", "eth_sendRawPrivateTransaction", new String[] {RAW_TRANSACTION_STRING}));
assertThatThrownBy(() -> method.response(request2))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 1");
}
@Test
public void requestHasNullObjectParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("2.0", "eth_sendRawPrivateTransaction", null));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void requestHasNullArrayParameter() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest("2.0", "\"eth_sendRawPrivateTransaction\"", new String[] {null}));
assertThatThrownBy(() -> method.response(request))
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void validTransactionIsSentToTransactionPool() {
when(enclave.sendSignedTransaction(any(), any())).thenReturn(null);
when(transactionPool.addLocalTransaction(any(Transaction.class)))
.thenReturn(ValidationResult.valid());
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0",
"\"eth_sendRawPrivateTransaction\"",
new Object[] {RAW_TRANSACTION, GO_QUORUM_SEND_RAW_TX_ARGS}));
method.response(request);
verify(transactionPool).addLocalTransaction(any(Transaction.class));
}
@Test
public void invalidTransactionIsNotAddedToTransactionPool() {
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0",
"\"eth_sendRawPrivateTransaction\"",
new Object[] {INVALID_TRANSACTION_RLP, GO_QUORUM_SEND_RAW_TX_ARGS}));
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(request.getRequest().getId(), JsonRpcError.DECODE_ERROR);
final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
verifyNoInteractions(transactionPool);
}
@Test
public void transactionWithNonceBelowAccountNonceIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.NONCE_TOO_LOW, JsonRpcError.NONCE_TOO_LOW);
}
@Test
public void transactionWithNonceAboveAccountNonceIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.NONCE_TOO_HIGH, JsonRpcError.NONCE_TOO_HIGH);
}
@Test
public void transactionWithInvalidSignatureIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.INVALID_SIGNATURE, JsonRpcError.INVALID_TRANSACTION_SIGNATURE);
}
@Test
public void transactionWithIntrinsicGasExceedingGasLimitIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.INTRINSIC_GAS_EXCEEDS_GAS_LIMIT,
JsonRpcError.PMT_FAILED_INTRINSIC_GAS_EXCEEDS_LIMIT);
}
@Test
public void transactionWithUpfrontGasExceedingAccountBalanceIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE,
JsonRpcError.TRANSACTION_UPFRONT_COST_EXCEEDS_BALANCE);
}
@Test
public void transactionWithGasLimitExceedingBlockGasLimitIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT, JsonRpcError.EXCEEDS_BLOCK_GAS_LIMIT);
}
@Test
public void transactionWithNotWhitelistedSenderAccountIsRejected() {
verifyErrorForInvalidTransaction(
TransactionInvalidReason.TX_SENDER_NOT_AUTHORIZED, JsonRpcError.TX_SENDER_NOT_AUTHORIZED);
}
private void verifyErrorForInvalidTransaction(
final TransactionInvalidReason transactionInvalidReason, final JsonRpcError expectedError) {
when(transactionPool.addLocalTransaction(any(Transaction.class)))
.thenReturn(ValidationResult.invalid(transactionInvalidReason));
final JsonRpcRequestContext request =
new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0",
"\"eth_sendRawPrivateTransaction\"",
new Object[] {RAW_TRANSACTION, GO_QUORUM_SEND_RAW_TX_ARGS}));
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(request.getRequest().getId(), expectedError);
final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).usingRecursiveComparison().isEqualTo(expectedResponse);
verify(transactionPool).addLocalTransaction(any(Transaction.class));
}
private static String invalidGQPrivateTransactionRlp() {
final PrivateTransaction.Builder privateTransactionBuilder =
PrivateTransaction.builder()
.nonce(0)
.gasPrice(Wei.of(1))
.gasLimit(21000)
.value(Wei.ZERO)
.payload(Bytes.EMPTY)
.to(Address.fromHexString("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"))
.chainId(BigInteger.ONE)
.privateFrom(Bytes.fromBase64String("S28yYlZxRCtuTmxOWUw1RUU3eTNJZE9udmlmdGppaXp="))
.privateFor(
List.of(
Bytes.fromBase64String("S28yYlZxRCtuTmxOWUw1RUU3eTNJZE9udmlmdGppaXp="),
Bytes.fromBase64String("QTFhVnRNeExDVUhtQlZIWG9aenpCZ1BiVy93ajVheER=")))
.restriction(Restriction.RESTRICTED);
return rlpEncodeTransaction(privateTransactionBuilder);
}
private static String rlpEncodeTransaction(
final PrivateTransaction.Builder privateTransactionBuilder) {
final KeyPair keyPair =
SIGNATURE_ALGORITHM
.get()
.createKeyPair(
SIGNATURE_ALGORITHM
.get()
.createPrivateKey(
new BigInteger(
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63",
16)));
final PrivateTransaction privateTransaction = privateTransactionBuilder.signAndBuild(keyPair);
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlp);
return bvrlp.encoded().toHexString();
}
private static final String createValidTransactionRLP() {
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
final Transaction publicTransaction =
new Transaction(
0L,
Wei.of(1),
21000L,
Optional.of(
Address.wrap(Bytes.fromHexString("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"))),
Wei.ZERO,
SIGNATURE_ALGORITHM
.get()
.createSignature(
new BigInteger(
"32886959230931919120748662916110619501838190146643992583529828535682419954515"),
new BigInteger(
"14473701025599600909210599917245952381483216609124029382871721729679842002948"),
Byte.parseByte("0")),
Bytes.fromHexString("0x01"), // this is the enclave key for the private payload
Address.wrap(
Bytes.fromHexString(
"0x8411b12666f68ef74cace3615c9d5a377729d03f")), // sender public address
Optional.empty(),
Optional.of(BigInteger.valueOf(37)),
Optional.empty());
publicTransaction.writeTo(bvrlp);
return bvrlp.encoded().toHexString();
}
}

@ -35,7 +35,6 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -92,7 +91,6 @@ public class RewardTraceGeneratorTest {
blockReward,
BlockHeader::getCoinbase,
true,
Optional.empty(),
protocolSchedule);
when(protocolSpec.getBlockProcessor()).thenReturn(blockProcessor);

@ -1,132 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.ethereum.api.query;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class GoQuorumPrivateTxBloomBlockchainQueriesTest {
@ClassRule public static TemporaryFolder cacheDir = new TemporaryFolder();
private static LogsQuery logsQuery;
private Hash testHash;
private static LogsBloomFilter testLogsBloomFilter;
@Mock MutableBlockchain blockchain;
@Mock WorldStateArchive worldStateArchive;
@Mock EthScheduler scheduler;
private BlockchainQueries blockchainQueries;
@BeforeClass
public static void setupClass() {
final Address testAddress = Address.fromHexString("0x123456");
final Bytes testMessage = Bytes.fromHexString("0x9876");
final Log testLog = new Log(testAddress, testMessage, List.of());
testLogsBloomFilter = LogsBloomFilter.builder().insertLog(testLog).build();
logsQuery = new LogsQuery(List.of(testAddress), List.of());
}
@Before
public void setup() {
final BlockHeader fakeHeader =
new BlockHeader(
Hash.EMPTY,
Hash.EMPTY,
Address.ZERO,
Hash.EMPTY,
Hash.EMPTY,
Hash.EMPTY,
LogsBloomFilter.empty(),
Difficulty.ZERO,
0,
0,
0,
0,
Bytes.EMPTY,
null,
Hash.EMPTY,
0,
null,
null,
null,
new MainnetBlockHeaderFunctions(),
Optional.of(testLogsBloomFilter));
testHash = fakeHeader.getHash();
final BlockBody fakeBody = new BlockBody(Collections.emptyList(), Collections.emptyList());
when(blockchain.getBlockHeader(any())).thenReturn(Optional.of(fakeHeader));
when(blockchain.getBlockHeader(anyLong())).thenReturn(Optional.of(fakeHeader));
when(blockchain.getTxReceipts(any())).thenReturn(Optional.of(Collections.emptyList()));
when(blockchain.getBlockBody(any())).thenReturn(Optional.of(fakeBody));
blockchainQueries =
new BlockchainQueries(
blockchain,
worldStateArchive,
Optional.of(cacheDir.getRoot().toPath()),
Optional.of(scheduler));
}
/**
* Tests whether block headers containing private blooms match. The resulting list of
* LogWithMetadata would be empty, because the mocked blockchain does not return any receipts, but
* we do check that the methods on the blockchain are actually called that would be called if the
* block header matches the bloom filter.
*/
@Test
public void testPrivateBloomsWork() {
blockchainQueries.matchingLogs(0, 2, logsQuery, () -> true);
verify(blockchain, times(3)).getBlockHeader(anyLong());
verify(blockchain, times(3)).getBlockHeader(testHash);
verify(blockchain, times(3)).getTxReceipts(testHash);
verify(blockchain, times(3)).getBlockBody(testHash);
verify(blockchain, times(3)).blockIsOnCanonicalChain(testHash);
verifyNoMoreInteractions(blockchain);
}
}

@ -1,178 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.ethereum.api.query.cache;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.query.cache.TransactionLogBloomCacher.BLOOM_BITS_LENGTH;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.api.query.LogsQuery;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings({"unused", "DirectInvocationOnMock"})
public class GoQuorumPrivateTransactionLogBloomCacherTest {
private static final long NUMBER_3 = 3L;
private static LogsQuery logsQuery;
@Rule public TemporaryFolder cacheDir = new TemporaryFolder();
private Hash testBlockHeaderHash;
private static LogsBloomFilter testLogsBloomFilter;
@Mock MutableBlockchain blockchain;
@Mock EthScheduler scheduler;
@Mock WorldStateArchive worldStateArchive;
private TransactionLogBloomCacher transactionLogBloomCacher;
private BlockchainQueries blockchainQueries;
private static Address testAddress;
private static Bytes testMessage;
private BlockHeader fakeHeader;
@BeforeClass
public static void setupClass() {
testAddress = Address.fromHexString("0x123456");
testMessage = Bytes.fromHexString("0x9876");
final Log testLog = new Log(testAddress, testMessage, List.of());
testLogsBloomFilter = LogsBloomFilter.builder().insertLog(testLog).build();
logsQuery = new LogsQuery(List.of(testAddress), List.of());
}
@SuppressWarnings({"unchecked", "ReturnValueIgnored"})
@Before
public void setup() throws IOException {
fakeHeader = createBlock(NUMBER_3);
testBlockHeaderHash = fakeHeader.getHash();
transactionLogBloomCacher =
new TransactionLogBloomCacher(blockchain, cacheDir.getRoot().toPath(), scheduler);
blockchainQueries =
new BlockchainQueries(
blockchain,
worldStateArchive,
Optional.of(cacheDir.getRoot().toPath()),
Optional.of(scheduler));
}
@Test
public void shouldUpdateCacheWhenBlockAdded() throws IOException {
final BlockBody fakeBody = new BlockBody(Collections.emptyList(), Collections.emptyList());
when(blockchain.getBlockHeader(testBlockHeaderHash)).thenReturn(Optional.of(fakeHeader));
when(blockchain.getBlockHashByNumber(anyLong())).thenReturn(Optional.of(testBlockHeaderHash));
when(blockchain.getTxReceipts(any())).thenReturn(Optional.of(Collections.emptyList()));
when(blockchain.getBlockBody(any())).thenReturn(Optional.of(fakeBody));
final File logBloom = cacheDir.newFile("logBloom-0.cache");
createLogBloomCache(logBloom);
createBlock(3L);
assertThat(logBloom.length()).isEqualTo(BLOOM_BITS_LENGTH * 3);
when(blockchain.getBlockHeader(anyLong())).thenReturn(Optional.of(fakeHeader));
transactionLogBloomCacher.cacheLogsBloomForBlockHeader(
blockchain.getBlockHeader(NUMBER_3).get(), Optional.empty(), Optional.of(logBloom));
assertThat(logBloom.length()).isEqualTo(BLOOM_BITS_LENGTH * 4);
assertThat(cacheDir.getRoot().list().length).isEqualTo(1);
blockchainQueries.matchingLogs(NUMBER_3, 3, logsQuery, () -> true);
verify(blockchain, times(1)).getBlockHashByNumber(NUMBER_3);
verify(blockchain, times(1)).getBlockHeader(NUMBER_3);
verify(blockchain, times(1)).getBlockHeader(testBlockHeaderHash);
verify(blockchain, times(1)).getTxReceipts(testBlockHeaderHash);
verify(blockchain, times(1)).getBlockBody(testBlockHeaderHash);
verify(blockchain, times(1)).blockIsOnCanonicalChain(testBlockHeaderHash);
verifyNoMoreInteractions(blockchain);
}
private void createLogBloomCache(final File logBloom) throws IOException {
try (final RandomAccessFile randomAccessFile = new RandomAccessFile(logBloom, "rws")) {
randomAccessFile.write(testLogsBloomFilter.toArray());
randomAccessFile.write(testLogsBloomFilter.toArray());
randomAccessFile.write(testLogsBloomFilter.toArray());
}
}
private BlockHeader createBlock(final long number) {
final Log testLog = new Log(testAddress, testMessage, List.of());
final BlockHeader fakeHeader =
new BlockHeader(
Hash.EMPTY,
Hash.EMPTY,
Address.ZERO,
Hash.EMPTY,
Hash.EMPTY,
Hash.EMPTY,
LogsBloomFilter.empty(),
Difficulty.ZERO,
number,
0,
0,
0,
Bytes.EMPTY,
null,
Hash.EMPTY,
0,
null,
null,
null,
new MainnetBlockHeaderFunctions(),
Optional.of(testLogsBloomFilter));
return fakeHeader;
}
}

@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions.TransactionSelectionResult;
import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
@ -34,13 +33,11 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.TransactionType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@ -50,7 +47,6 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -327,40 +323,18 @@ public class BlockTransactionSelector {
final WorldUpdater worldStateUpdater = worldState.updater();
final BlockHashLookup blockHashLookup =
new CachingBlockHashLookup(processableBlockHeader, blockchain);
final boolean isGoQuorumPrivateTransaction =
transaction.isGoQuorumPrivateTransaction(
transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode());
TransactionProcessingResult effectiveResult;
if (isGoQuorumPrivateTransaction) {
final ValidationResult<TransactionInvalidReason> validationResult =
validateTransaction(processableBlockHeader, transaction, worldStateUpdater);
if (!validationResult.isValid()) {
LOG.warn(
"Invalid transaction: {}. Block {} Transaction {}",
validationResult.getErrorMessage(),
processableBlockHeader.getParentHash().toHexString(),
transaction.getHash().toHexString());
return transactionSelectionResultForInvalidResult(transaction, validationResult);
} else {
// valid GoQuorum private tx, we need to handcraft the receipt and increment the nonce
effectiveResult = publicResultForWhenWeHaveAPrivateTransaction(transaction);
worldStateUpdater.getOrCreate(transaction.getSender()).getMutable().incrementNonce();
}
} else {
effectiveResult =
transactionProcessor.processTransaction(
blockchain,
worldStateUpdater,
processableBlockHeader,
transaction,
miningBeneficiary,
blockHashLookup,
false,
TransactionValidationParams.mining(),
dataGasPrice);
}
final TransactionProcessingResult effectiveResult =
transactionProcessor.processTransaction(
blockchain,
worldStateUpdater,
processableBlockHeader,
transaction,
miningBeneficiary,
blockHashLookup,
false,
TransactionValidationParams.mining(),
dataGasPrice);
if (!effectiveResult.isInvalid()) {
worldStateUpdater.commit();
@ -445,42 +419,14 @@ public class BlockTransactionSelector {
|| invalidReason.equals(TransactionInvalidReason.NONCE_TOO_HIGH);
}
private ValidationResult<TransactionInvalidReason> validateTransaction(
final ProcessableBlockHeader blockHeader,
final Transaction transaction,
final WorldUpdater publicWorldStateUpdater) {
final TransactionValidationParams transactionValidationParams =
TransactionValidationParams.processingBlock();
final MainnetTransactionValidator transactionValidator =
transactionProcessor.getTransactionValidator();
ValidationResult<TransactionInvalidReason> validationResult =
transactionValidator.validate(
transaction, blockHeader.getBaseFee(), transactionValidationParams);
if (!validationResult.isValid()) {
return validationResult;
}
final Address senderAddress = transaction.getSender();
final EvmAccount sender = publicWorldStateUpdater.getOrCreate(senderAddress);
validationResult =
transactionValidator.validateForSender(transaction, sender, transactionValidationParams);
return validationResult;
}
/*
Responsible for updating the state maintained between transaction validation (i.e. receipts,
cumulative gas, world state root hash.).
*/
private void updateTransactionResultTracking(
final Transaction transaction, final TransactionProcessingResult result) {
final boolean isGoQuorumPrivateTransaction =
transaction.isGoQuorumPrivateTransaction(
transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode());
final long gasUsedByTransaction =
isGoQuorumPrivateTransaction ? 0 : transaction.getGasLimit() - result.getGasRemaining();
final long gasUsedByTransaction = transaction.getGasLimit() - result.getGasRemaining();
final long cumulativeGasUsed =
transactionSelectionResult.getCumulativeGasUsed() + gasUsedByTransaction;
@ -499,16 +445,6 @@ public class BlockTransactionSelector {
return result.getInvalidReason().equals(TransactionInvalidReason.NONCE_TOO_HIGH);
}
private TransactionProcessingResult publicResultForWhenWeHaveAPrivateTransaction(
final Transaction transaction) {
return TransactionProcessingResult.successful(
Collections.emptyList(),
0,
transaction.getGasLimit(),
Bytes.EMPTY,
ValidationResult.valid());
}
private boolean transactionTooLargeForBlock(final Transaction transaction) {
final long dataGasUsed = gasCalculator.dataGasCost(transaction.getBlobCount());

@ -148,7 +148,6 @@ abstract class AbstractBlockCreatorTest {
protocolSpecAdapters,
PrivacyParameters.DEFAULT,
false,
genesisConfigOptions.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule())
.build();

@ -92,8 +92,6 @@ public abstract class AbstractBlockTransactionSelectorTest {
public void setup() {
worldState = InMemoryKeyValueStorageProvider.createInMemoryWorldState();
pendingTransactions = createPendingTransactions();
when(transactionProcessor.getTransactionValidator()).thenReturn(transactionValidator);
when(transactionValidator.getGoQuorumCompatibilityMode()).thenReturn(true);
}
protected abstract PendingTransactions createPendingTransactions();

@ -80,7 +80,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
genesisConfigOptions.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule())
.build();
@ -142,7 +141,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
genesisConfigOptions.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule())
.build();
@ -194,7 +192,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
genesisConfigOptions.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =
@ -269,7 +266,6 @@ class PoWBlockCreatorTest extends AbstractBlockCreatorTest {
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
genesisConfigOptions.isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
final ExecutionContextTestFixture executionContextTestFixture =

@ -20,7 +20,6 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumBlockProcessingResult;
import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
@ -29,7 +28,6 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -146,25 +144,6 @@ public class MainnetBlockValidator implements BlockValidator {
handleAndLogImportFailure(block, result, shouldRecordBadBlock);
return new BlockProcessingResult("failed to validate output of imported block");
}
if (result instanceof GoQuorumBlockProcessingResult) {
var privateOutput = (GoQuorumBlockProcessingResult) result;
if (!privateOutput.getPrivateReceipts().isEmpty()) {
// replace the public receipts for marker transactions with the private receipts if we
// are in goQuorumCompatibilityMode. That can be done now because we have validated the
// block.
final List<TransactionReceipt> privateTransactionReceipts =
privateOutput.getPrivateReceipts();
final ArrayList<TransactionReceipt> resultingList = new ArrayList<>(receipts.size());
for (int i = 0; i < receipts.size(); i++) {
if (privateTransactionReceipts.get(i) != null) {
resultingList.add(privateTransactionReceipts.get(i));
} else {
resultingList.add(receipts.get(i));
}
}
receipts = Collections.unmodifiableList(resultingList);
}
}
return new BlockProcessingResult(
Optional.of(new BlockProcessingOutputs(worldState, receipts)));

@ -42,8 +42,6 @@ public class BlockHeader extends SealableBlockHeader
private final Supplier<Hash> hash;
private Optional<LogsBloomFilter> privateLogsBloom;
private final Supplier<ParsedExtraData> parsedExtraData;
public BlockHeader(
@ -90,7 +88,6 @@ public class BlockHeader extends SealableBlockHeader
this.nonce = nonce;
this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this));
this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this));
this.privateLogsBloom = privateLogsBloom;
}
public BlockHeader(
@ -136,7 +133,6 @@ public class BlockHeader extends SealableBlockHeader
this.nonce = nonce;
this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this));
this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this));
this.privateLogsBloom = Optional.empty();
}
/**
@ -187,31 +183,6 @@ public class BlockHeader extends SealableBlockHeader
return hash.get();
}
public LogsBloomFilter getLogsBloom(final boolean addPrivateBloom) {
if (addPrivateBloom && privateLogsBloom.isPresent()) {
return LogsBloomFilter.builder()
.insertFilter(logsBloom)
.insertFilter(privateLogsBloom.get())
.build();
} else {
return logsBloom;
}
}
public void setPrivateLogsBloom(final LogsBloomFilter privateLogsBloom) {
this.privateLogsBloom = Optional.ofNullable(privateLogsBloom);
}
/**
* Returns the block's private logs bloom filter that might be available if we are in goQuorum
* mode
*
* @return the private logs bloom filter
*/
public Optional<LogsBloomFilter> getPrivateLogsBloom() {
return privateLogsBloom;
}
/**
* Write an RLP representation.
*

@ -1,56 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.core;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStorage;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
public class GoQuorumPrivacyParameters {
private final GoQuorumEnclave enclave;
private final String enclaveKey;
private final GoQuorumPrivateStorage goQuorumPrivateStorage;
private final WorldStateArchive privateWorldStateArchive;
public GoQuorumPrivacyParameters(
final GoQuorumEnclave enclave,
final String enclaveKey,
final GoQuorumPrivateStorage goQuorumPrivateStorage,
final WorldStateArchive privateWorldStateArchive) {
this.enclave = enclave;
this.enclaveKey = enclaveKey;
this.goQuorumPrivateStorage = goQuorumPrivateStorage;
this.privateWorldStateArchive = privateWorldStateArchive;
}
public GoQuorumEnclave enclave() {
return enclave;
}
public String enclaveKey() {
return enclaveKey;
}
public GoQuorumPrivateStorage privateStorage() {
return goQuorumPrivateStorage;
}
public WorldStateArchive worldStateArchive() {
return privateWorldStateArchive;
}
}

@ -75,7 +75,6 @@ public class PrivacyParameters {
private boolean privacyPluginEnabled;
private PrivateStateRootResolver privateStateRootResolver;
private PrivateWorldStateReader privateWorldStateReader;
private Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters = Optional.empty();
private PrivacyPluginService privacyPluginService;
public Address getPrivacyAddress() {
@ -202,16 +201,6 @@ public class PrivacyParameters {
this.privateWorldStateReader = privateWorldStateReader;
}
public Optional<GoQuorumPrivacyParameters> getGoQuorumPrivacyParameters() {
return goQuorumPrivacyParameters;
}
private void setGoQuorumPrivacyParameters(
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters) {
this.goQuorumPrivacyParameters =
goQuorumPrivacyParameters != null ? goQuorumPrivacyParameters : Optional.empty();
}
private void setPrivacyService(final PrivacyPluginService privacyPluginService) {
this.privacyPluginService = privacyPluginService;
}
@ -272,7 +261,6 @@ public class PrivacyParameters {
private Path privacyTlsKnownEnclaveFile;
private boolean flexiblePrivacyGroupsEnabled;
private boolean privacyPluginEnabled;
private Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters;
private PrivacyPluginService privacyPluginService;
public Builder setEnclaveUrl(final URI enclaveUrl) {
@ -330,12 +318,6 @@ public class PrivacyParameters {
return this;
}
public Builder setGoQuorumPrivacyParameters(
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters) {
this.goQuorumPrivacyParameters = goQuorumPrivacyParameters;
return this;
}
public Builder setPrivacyUserIdUsingFile(final File publicKeyFile) throws IOException {
this.enclavePublicKeyFile = publicKeyFile;
this.privacyUserId = Files.asCharSource(publicKeyFile, UTF_8).read();
@ -398,7 +380,6 @@ public class PrivacyParameters {
config.setMultiTenancyEnabled(multiTenancyEnabled);
config.setFlexiblePrivacyGroupsEnabled(flexiblePrivacyGroupsEnabled);
config.setPrivacyPluginEnabled(privacyPluginEnabled);
config.setGoQuorumPrivacyParameters(goQuorumPrivacyParameters);
return config;
}
}

@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
import org.hyperledger.besu.ethereum.transaction.GoQuorumPrivateTransactionDetector;
import org.hyperledger.besu.evm.AccessListEntry;
import org.hyperledger.besu.plugin.data.TransactionType;
@ -63,9 +62,6 @@ public class Transaction
public static final BigInteger REPLAY_PROTECTED_V_BASE = BigInteger.valueOf(35);
public static final BigInteger GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MIN = BigInteger.valueOf(37);
public static final BigInteger GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MAX = BigInteger.valueOf(38);
// The v signature parameter starts at 36 because 1 is the first valid chainId so:
// chainId > 1 implies that 2 * chainId + V_BASE > 36.
public static final BigInteger REPLAY_PROTECTED_V_MIN = BigInteger.valueOf(36);
@ -95,8 +91,6 @@ public class Transaction
private final Optional<BigInteger> chainId;
private final Optional<BigInteger> v;
// Caches a "hash" of a portion of the transaction used for sender recovery.
// Note that this hash does not include the transaction signature so it does not
// fully identify the transaction (use the result of the {@code hash()} for that).
@ -145,9 +139,6 @@ public class Transaction
* preload
* @param sender the transaction sender
* @param chainId the chain id to apply the transaction to
* @param v the v value. This is only passed in directly for GoQuorum private transactions
* (v=37|38). For all other transactions, the v value is derived from the signature. If v is
* provided here, the chain id must be empty.
* <p>The {@code to} will be an {@code Optional.empty()} for a contract creation transaction;
* otherwise it should contain an address.
* <p>The {@code chainId} must be greater than 0 to be applied to a specific chain; otherwise
@ -168,12 +159,7 @@ public class Transaction
final Optional<List<AccessListEntry>> maybeAccessList,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v,
final Optional<List<Hash>> versionedHashes) {
if (v.isPresent() && chainId.isPresent()) {
throw new IllegalArgumentException(
String.format("chainId '%s' and v '%s' cannot both be provided", chainId.get(), v.get()));
}
if (transactionType.requiresChainId()) {
checkArgument(
@ -218,7 +204,6 @@ public class Transaction
this.maybeAccessList = maybeAccessList;
this.sender = sender;
this.chainId = chainId;
this.v = v;
this.versionedHashes = versionedHashes;
if (isUpfrontGasCostTooHigh()) {
@ -239,7 +224,6 @@ public class Transaction
final Bytes payload,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v,
final Optional<List<Hash>> versionedHashes) {
this(
TransactionType.FRONTIER,
@ -256,7 +240,6 @@ public class Transaction
Optional.empty(),
sender,
chainId,
v,
versionedHashes);
}
@ -269,7 +252,6 @@ public class Transaction
final SECPSignature signature,
final Bytes payload,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v,
final Optional<List<Hash>> versionedHashes) {
this(
TransactionType.FRONTIER,
@ -286,52 +268,6 @@ public class Transaction
Optional.empty(),
null,
chainId,
v,
versionedHashes);
}
/**
* Instantiates a transaction instance.
*
* @param nonce the nonce
* @param gasPrice the gas price
* @param gasLimit the gas limit
* @param to the transaction recipient
* @param value the value being transferred to the recipient
* @param signature the signature
* @param payload the payload
* @param sender the transaction sender
* @param chainId the chain id to apply the transaction to
* <p>The {@code to} will be an {@code Optional.empty()} for a contract creation transaction;
* otherwise it should contain an address.
* <p>The {@code chainId} must be greater than 0 to be applied to a specific chain; otherwise
* it will default to any chain.
*/
public Transaction(
final long nonce,
final Wei gasPrice,
final long gasLimit,
final Optional<Address> to,
final Wei value,
final SECPSignature signature,
final Bytes payload,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<List<Hash>> versionedHashes) {
this(
nonce,
Optional.of(gasPrice),
Optional.empty(),
Optional.empty(),
Optional.empty(),
gasLimit,
to,
value,
signature,
payload,
sender,
chainId,
Optional.empty(),
versionedHashes);
}
@ -347,7 +283,6 @@ public class Transaction
* @param payload the payload
* @param sender the transaction sender
* @param chainId the chain id to apply the transaction to
* @param v the v value (only passed in directly for GoQuorum private transactions)
* <p>The {@code to} will be an {@code Optional.empty()} for a contract creation transaction;
* otherwise it should contain an address.
* <p>The {@code chainId} must be greater than 0 to be applied to a specific chain; otherwise
@ -363,7 +298,6 @@ public class Transaction
final Bytes payload,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v,
final Optional<List<Hash>> versionedHashes) {
this(
nonce,
@ -378,7 +312,6 @@ public class Transaction
payload,
sender,
chainId,
v,
versionedHashes);
}
@ -638,9 +571,6 @@ public class Transaction
@Override
public BigInteger getV() {
if (this.v.isPresent()) {
return this.v.get();
}
final BigInteger recId = BigInteger.valueOf(signature.getRecId());
@ -813,16 +743,7 @@ public class Transaction
* @return true if GoQuorum private transaction, false otherwise
*/
public boolean isGoQuorumPrivateTransaction(final boolean goQuorumCompatibilityMode) {
if (!goQuorumCompatibilityMode) {
return false;
}
if (chainId.isPresent()) {
return false;
}
if (!v.isPresent()) {
return false;
}
return GoQuorumPrivateTransactionDetector.isGoQuorumPrivateTransactionV(v.get());
return false;
}
/**
@ -1073,8 +994,7 @@ public class Transaction
value,
payload,
signature,
chainId,
v);
chainId);
}
@Override
@ -1102,7 +1022,6 @@ public class Transaction
sb.append("value=").append(getValue()).append(", ");
sb.append("sig=").append(getSignature()).append(", ");
if (chainId.isPresent()) sb.append("chainId=").append(getChainId().get()).append(", ");
if (v.isPresent()) sb.append("v=").append(v.get()).append(", ");
sb.append("payload=").append(getPayload());
if (transactionType.equals(TransactionType.ACCESS_LIST)) {
sb.append(", ").append("accessList=").append(maybeAccessList);
@ -1281,7 +1200,6 @@ public class Transaction
accessList,
sender,
chainId,
v,
Optional.ofNullable(versionedHashes));
}

@ -15,14 +15,12 @@
package org.hyperledger.besu.ethereum.core.encoding;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.hyperledger.besu.ethereum.core.Transaction.GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MIN;
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_BASE;
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_MIN;
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE;
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE_PLUS_1;
import static org.hyperledger.besu.ethereum.core.Transaction.TWO;
import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.crypto.SECPSignature;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
@ -31,7 +29,6 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.transaction.GoQuorumPrivateTransactionDetector;
import org.hyperledger.besu.evm.AccessListEntry;
import org.hyperledger.besu.plugin.data.TransactionType;
@ -61,13 +58,8 @@ public class TransactionDecoder {
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
public static Transaction decodeForWire(final RLPInput rlpInput) {
return decodeForWire(rlpInput, GoQuorumOptions.getGoQuorumCompatibilityMode());
}
public static Transaction decodeForWire(
final RLPInput rlpInput, final boolean goQuorumCompatibilityMode) {
if (rlpInput.nextIsList()) {
return decodeFrontier(rlpInput, goQuorumCompatibilityMode);
return decodeFrontier(rlpInput);
} else {
final Bytes typedTransactionBytes = rlpInput.readBytes();
final TransactionType transactionType =
@ -77,16 +69,11 @@ public class TransactionDecoder {
}
public static Transaction decodeOpaqueBytes(final Bytes input) {
return decodeOpaqueBytes(input, GoQuorumOptions.getGoQuorumCompatibilityMode());
}
public static Transaction decodeOpaqueBytes(
final Bytes input, final boolean goQuorumCompatibilityMode) {
final TransactionType transactionType;
try {
transactionType = TransactionType.of(input.get(0));
} catch (final IllegalArgumentException __) {
return decodeForWire(RLP.input(input), goQuorumCompatibilityMode);
return decodeForWire(RLP.input(input));
}
return getDecoder(transactionType).decode(RLP.input(input.slice(1)));
}
@ -98,7 +85,7 @@ public class TransactionDecoder {
transactionType);
}
static Transaction decodeFrontier(final RLPInput input, final boolean goQuorumCompatibilityMode) {
static Transaction decodeFrontier(final RLPInput input) {
input.enterList();
final Transaction.Builder builder =
Transaction.builder()
@ -113,11 +100,7 @@ public class TransactionDecoder {
final BigInteger v = input.readBigIntegerScalar();
final byte recId;
Optional<BigInteger> chainId = Optional.empty();
if (goQuorumCompatibilityMode
&& GoQuorumPrivateTransactionDetector.isGoQuorumPrivateTransactionV(v)) {
builder.v(v);
recId = v.subtract(GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MIN).byteValueExact();
} else if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) {
if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) {
recId = v.subtract(REPLAY_UNPROTECTED_V_BASE).byteValueExact();
} else if (v.compareTo(REPLAY_PROTECTED_V_MIN) > 0) {
chainId = Optional.of(v.subtract(REPLAY_PROTECTED_V_BASE).divide(TWO));

@ -37,7 +37,6 @@ public class FixedDifficultyProtocolSchedule {
builder.difficultyCalculator(FixedDifficultyCalculators.calculator(config))),
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
evmConfiguration)
.createProtocolSchedule();
}

@ -1,44 +0,0 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package org.hyperledger.besu.ethereum.goquorum;
import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class GoQuorumBlockProcessingResult extends BlockProcessingResult {
public final Optional<BlockProcessingOutputs> privateYield;
public GoQuorumBlockProcessingResult(
final BlockProcessingOutputs mainnetYield, final BlockProcessingOutputs privateYield) {
super(Optional.of(mainnetYield));
this.privateYield = Optional.ofNullable(privateYield);
}
public List<TransactionReceipt> getPrivateReceipts() {
if (privateYield.isEmpty()) {
return new ArrayList<>();
} else {
return privateYield.get().getReceipts();
}
}
}

@ -1,303 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.EnclaveClientException;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.enclave.types.GoQuorumReceiveResponse;
import org.hyperledger.besu.ethereum.BlockProcessingOutputs;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.worldstate.GoQuorumMutablePrivateWorldStateUpdater;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoQuorumBlockProcessor extends MainnetBlockProcessor {
private static final Logger LOG = LoggerFactory.getLogger(GoQuorumBlockProcessor.class);
private final GoQuorumEnclave goQuorumEnclave;
private final GoQuorumPrivateStorage goQuorumPrivateStorage;
public GoQuorumBlockProcessor(
final MainnetTransactionProcessor transactionProcessor,
final TransactionReceiptFactory transactionReceiptFactory,
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final HeaderBasedProtocolSchedule protocolSchedule) {
super(
transactionProcessor,
transactionReceiptFactory,
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
Optional.empty(),
protocolSchedule);
this.goQuorumEnclave = goQuorumPrivacyParameters.orElseThrow().enclave();
this.goQuorumPrivateStorage = goQuorumPrivacyParameters.orElseThrow().privateStorage();
}
@Override
public BlockProcessingResult processBlock(
final Blockchain blockchain,
final MutableWorldState publicWorldState,
final MutableWorldState privateWorldState,
final Block block) {
final BlockHeader blockHeader = block.getHeader();
final List<Transaction> transactions = block.getBody().getTransactions();
final List<BlockHeader> ommers = block.getBody().getOmmers();
final List<TransactionReceipt> publicTxReceipts = new ArrayList<>();
final List<TransactionReceipt> privateTxReceipts = new ArrayList<>();
long currentGasUsed = 0;
final GoQuorumPrivateStorage.Updater privateStorageUpdater = goQuorumPrivateStorage.updater();
for (final Transaction transaction : transactions) {
if (!hasAvailableBlockBudget(blockHeader, transaction, currentGasUsed)) {
return new BlockProcessingResult(Optional.empty(), "insufficient gas");
}
final WorldUpdater publicWorldStateUpdater = publicWorldState.updater();
final BlockHashLookup blockHashLookup = new CachingBlockHashLookup(blockHeader, blockchain);
final Address miningBeneficiary =
miningBeneficiaryCalculator.calculateBeneficiary(blockHeader);
WorldUpdater effectiveWorldUpdater = null;
Transaction effectiveTransaction;
final boolean isGoQuorumPrivateTransaction =
transaction.isGoQuorumPrivateTransaction(
transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode());
if (isGoQuorumPrivateTransaction) { // private transaction
try {
effectiveTransaction = retrievePrivateTransactionFromEnclave(transaction);
effectiveWorldUpdater =
new GoQuorumMutablePrivateWorldStateUpdater(
publicWorldStateUpdater, privateWorldState.updater());
} catch (final EnclaveClientException e) { // private transaction but not party to it
// We do not have to execute anything, but we still need to validate the transaction
effectiveTransaction = null;
final ValidationResult<TransactionInvalidReason> validationResult =
validateTransaction(blockHeader, transaction, publicWorldStateUpdater);
if (!validationResult.isValid()) {
return new BlockProcessingResult(Optional.empty(), e);
}
}
} else { // public Transaction
effectiveWorldUpdater = publicWorldState.updater();
effectiveTransaction = transaction;
}
if (effectiveTransaction != null) { // public tx, or private tx that we are party to
final TransactionProcessingResult result =
transactionProcessor.processTransaction(
blockchain,
effectiveWorldUpdater,
blockHeader,
effectiveTransaction,
miningBeneficiary,
OperationTracer.NO_TRACING,
blockHashLookup,
true,
TransactionValidationParams.processingBlock(),
null,
Wei.ZERO);
if (result.isInvalid()) {
String errorMessage =
MessageFormat.format(
"Block processing error: transaction invalid '{}'. Block {} Transaction {}",
result.getValidationResult().getErrorMessage(),
blockHeader.getHash().toHexString(),
transaction.getHash().toHexString());
LOG.info(errorMessage);
return new BlockProcessingResult(Optional.empty(), errorMessage);
}
if (isGoQuorumPrivateTransaction) { // private transaction we are party to
publicTxReceipts.add(
transactionReceiptFactory.create(
transaction.getType(),
publicResultForWhenWeHaveAPrivateTransaction(transaction),
publicWorldState,
currentGasUsed));
privateTxReceipts.add(
transactionReceiptFactory.create(
transaction.getType(), result, privateWorldState, currentGasUsed));
publicWorldStateUpdater
.getOrCreate(effectiveTransaction.getSender())
.getMutable()
.incrementNonce();
effectiveWorldUpdater.commit();
} else { // public transaction
final long gasUsed = transaction.getGasLimit() - result.getGasRemaining();
currentGasUsed += gasUsed;
publicTxReceipts.add(
transactionReceiptFactory.create(
transaction.getType(), result, publicWorldState, currentGasUsed));
privateTxReceipts.add(null);
effectiveWorldUpdater.commit();
}
} else { // private transaction we are not party to
publicTxReceipts.add(
transactionReceiptFactory.create(
transaction.getType(),
publicResultForWhenWeHaveAPrivateTransaction(transaction),
publicWorldState,
currentGasUsed));
privateTxReceipts.add(null);
publicWorldStateUpdater.getOrCreate(transaction.getSender()).getMutable().incrementNonce();
}
publicWorldStateUpdater.commit();
}
if (!rewardCoinbase(publicWorldState, blockHeader, ommers, skipZeroBlockRewards)) {
// no need to log, rewardCoinbase logs the error.
return new BlockProcessingResult(Optional.empty(), "ommer too old");
}
// create the bloom for the private transactions in the block and store it
final LogsBloomFilter.Builder privateBloomBuilder = LogsBloomFilter.builder();
privateTxReceipts.stream()
.filter(Objects::nonNull)
.forEach(pr -> privateBloomBuilder.insertFilter(pr.getBloomFilter()));
blockHeader.setPrivateLogsBloom(privateBloomBuilder.build());
publicWorldState.persist(blockHeader);
privateWorldState.persist(null);
privateStorageUpdater.putPrivateStateRootHashMapping(
publicWorldState.rootHash(), privateWorldState.rootHash());
privateStorageUpdater.commit();
BlockProcessingOutputs mainnetYield =
new BlockProcessingOutputs(publicWorldState, publicTxReceipts);
BlockProcessingOutputs privateYield =
new BlockProcessingOutputs(privateWorldState, privateTxReceipts);
return new GoQuorumBlockProcessingResult(mainnetYield, privateYield);
}
private ValidationResult<TransactionInvalidReason> validateTransaction(
final BlockHeader blockHeader,
final Transaction transaction,
final WorldUpdater publicWorldStateUpdater) {
final MainnetTransactionValidator transactionValidator =
transactionProcessor.getTransactionValidator();
final TransactionValidationParams transactionValidationParams =
TransactionValidationParams.processingBlock();
ValidationResult<TransactionInvalidReason> validationResult =
transactionValidator.validate(
transaction, blockHeader.getBaseFee(), transactionValidationParams);
if (!validationResult.isValid()) {
LOG.warn(
"Invalid transaction: {}. Block {} Transaction {}",
validationResult.getErrorMessage(),
blockHeader.getHash().toHexString(),
transaction.getHash().toHexString());
return validationResult;
}
final Address senderAddress = transaction.getSender();
final EvmAccount sender = publicWorldStateUpdater.getOrCreate(senderAddress);
validationResult =
transactionValidator.validateForSender(transaction, sender, transactionValidationParams);
if (!validationResult.isValid()) {
LOG.warn(
"Invalid transaction: {}. Block {} Transaction {}",
validationResult.getErrorMessage(),
blockHeader.getHash().toHexString(),
transaction.getHash().toHexString());
return validationResult;
}
return ValidationResult.valid();
}
private TransactionProcessingResult publicResultForWhenWeHaveAPrivateTransaction(
final Transaction transaction) {
return TransactionProcessingResult.successful(
Collections.emptyList(),
0,
transaction.getGasLimit(),
Bytes.EMPTY,
ValidationResult.valid());
}
private Transaction retrievePrivateTransactionFromEnclave(final Transaction transaction) {
final GoQuorumReceiveResponse receive =
goQuorumEnclave.receive(transaction.getPayload().toBase64String());
final Bytes privatePayload = Bytes.wrap(receive.getPayload());
return new Transaction(
transaction.getNonce(),
transaction.getGasPrice().get(),
transaction.getGasLimit(),
transaction.getTo(),
transaction.getValue(),
transaction.getSignature(),
privatePayload,
transaction
.getSender(), // at this point we are checking the signature of the public transaction
// and we are setting the sender for the private transaction, so the
// signature of the private transaction will not (and should not) be
// checked again.
transaction.getChainId(),
Optional.of(transaction.getV()),
Optional.empty());
}
}

@ -1,61 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import static org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStateUtil.getPrivateWorldState;
import org.hyperledger.besu.ethereum.BlockProcessingResult;
import org.hyperledger.besu.ethereum.MainnetBlockValidator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.BlockBodyValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator;
import org.hyperledger.besu.ethereum.mainnet.BlockProcessor;
import java.util.Optional;
public class GoQuorumBlockValidator extends MainnetBlockValidator {
private final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters;
public GoQuorumBlockValidator(
final BlockHeaderValidator blockHeaderValidator,
final BlockBodyValidator blockBodyValidator,
final BlockProcessor blockProcessor,
final BadBlockManager badBlockManager,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters) {
super(blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager);
this.goQuorumPrivacyParameters = goQuorumPrivacyParameters;
if (!(blockProcessor instanceof GoQuorumBlockProcessor)) {
throw new IllegalStateException(
"GoQuorumBlockValidator requires an instance of GoQuorumBlockProcessor");
}
}
@Override
protected BlockProcessingResult processBlock(
final ProtocolContext context, final MutableWorldState worldState, final Block block) {
final MutableWorldState privateWorldState =
getPrivateWorldState(goQuorumPrivacyParameters, worldState.rootHash(), block.getHash());
return ((GoQuorumBlockProcessor) blockProcessor)
.processBlock(context.getBlockchain(), worldState, privateWorldState, block);
}
}

@ -1,81 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
public class GoQuorumPrivateKeyValueStorage implements GoQuorumPrivateStorage {
private static final Bytes PRIVATE_STATEROOT_SUFFIX = Bytes.of("PRIVSTATEROOT".getBytes(UTF_8));
private final KeyValueStorage keyValueStorage;
public GoQuorumPrivateKeyValueStorage(final KeyValueStorage keyValueStorage) {
this.keyValueStorage = keyValueStorage;
}
@Override
public Optional<Hash> getPrivateStateRootHash(final Hash publicStateRootHash) {
return get(publicStateRootHash, PRIVATE_STATEROOT_SUFFIX).map(Bytes32::wrap).map(Hash::wrap);
}
private Optional<Bytes> get(final Bytes key, final Bytes keySuffix) {
return keyValueStorage.get(Bytes.concatenate(key, keySuffix).toArrayUnsafe()).map(Bytes::wrap);
}
@Override
public GoQuorumPrivateStorage.Updater updater() {
return new Updater(keyValueStorage.startTransaction());
}
public static class Updater implements GoQuorumPrivateStorage.Updater {
private final KeyValueStorageTransaction transaction;
private Updater(final KeyValueStorageTransaction transaction) {
this.transaction = transaction;
}
@Override
public GoQuorumPrivateStorage.Updater putPrivateStateRootHashMapping(
final Hash publicStateRootHash, final Hash privateStateRootHash) {
set(publicStateRootHash, PRIVATE_STATEROOT_SUFFIX, privateStateRootHash);
return this;
}
@Override
public void commit() {
transaction.commit();
}
@Override
public void rollback() {
transaction.rollback();
}
private void set(final Bytes key, final Bytes keySuffix, final Bytes value) {
transaction.put(Bytes.concatenate(key, keySuffix).toArrayUnsafe(), value.toArrayUnsafe());
}
}
}

@ -1,69 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GoQuorumPrivateStateUtil {
private static final Logger LOG = LoggerFactory.getLogger(GoQuorumPrivateStateUtil.class);
public static MutableWorldState getPrivateWorldStateAtBlock(
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final BlockHeader header) {
return getPrivateWorldState(goQuorumPrivacyParameters, header.getStateRoot(), header.getHash());
}
public static MutableWorldState getPrivateWorldState(
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final Hash worldStateRootHash,
final Hash publicBlockHash) {
final GoQuorumPrivateStorage goQuorumPrivateStorage =
goQuorumPrivacyParameters.orElseThrow().privateStorage();
final WorldStateArchive goQuorumWorldStateArchive =
goQuorumPrivacyParameters.orElseThrow().worldStateArchive();
final Hash privateStateRootHash =
goQuorumPrivateStorage
.getPrivateStateRootHash(worldStateRootHash)
.orElse(Hash.EMPTY_TRIE_HASH);
final Optional<MutableWorldState> maybePrivateWorldState =
goQuorumWorldStateArchive.getMutable(privateStateRootHash, publicBlockHash);
if (maybePrivateWorldState.isEmpty()) {
LOG.debug(
"Private world state not available for public world state root hash {}, public block hash {}",
worldStateRootHash,
publicBlockHash);
/*
This should never happen because privateStateRootResolver will either return a matching
private world state root hash, or the hash for an empty world state (first private tx ever).
*/
throw new IllegalStateException(
"Private world state not available for public world state root hash " + publicBlockHash);
}
return maybePrivateWorldState.get();
}
}

@ -1,36 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import org.hyperledger.besu.datatypes.Hash;
import java.util.Optional;
public interface GoQuorumPrivateStorage {
Optional<Hash> getPrivateStateRootHash(final Hash publicStateRootHash);
Updater updater();
interface Updater {
Updater putPrivateStateRootHashMapping(
final Hash publicStateRootHash, final Hash privateStateRootHash);
void commit();
void rollback();
}
}

@ -39,7 +39,6 @@ public abstract class AbstractProtocolScheduleBuilder {
protected final PrivacyParameters privacyParameters;
protected final boolean isRevertReasonEnabled;
protected final BadBlockManager badBlockManager = new BadBlockManager();
protected final boolean quorumCompatibilityMode;
protected final EvmConfiguration evmConfiguration;
protected AbstractProtocolScheduleBuilder(
@ -47,13 +46,11 @@ public abstract class AbstractProtocolScheduleBuilder {
final ProtocolSpecAdapters protocolSpecAdapters,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
this.config = config;
this.protocolSpecAdapters = protocolSpecAdapters;
this.privacyParameters = privacyParameters;
this.isRevertReasonEnabled = isRevertReasonEnabled;
this.quorumCompatibilityMode = quorumCompatibilityMode;
this.evmConfiguration = evmConfiguration;
}
@ -66,7 +63,6 @@ public abstract class AbstractProtocolScheduleBuilder {
config.getContractSizeLimit(),
config.getEvmStackSize(),
isRevertReasonEnabled,
quorumCompatibilityMode,
config.getEcip1017EraRounds(),
evmConfiguration);

@ -57,10 +57,9 @@ public class ClassicProtocolSpecs {
public static ProtocolSpecBuilder classicRecoveryInitDefinition(
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return MainnetProtocolSpecs.homesteadDefinition(
contractSizeLimit, configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
contractSizeLimit, configStackSizeLimit, evmConfiguration)
.blockHeaderValidatorBuilder(
feeMarket -> MainnetBlockHeaderValidator.createClassicValidator())
.name("ClassicRecoveryInit");
@ -70,15 +69,13 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId,
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return MainnetProtocolSpecs.homesteadDefinition(
contractSizeLimit, configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
contractSizeLimit, configStackSizeLimit, evmConfiguration)
.gasCalculator(TangerineWhistleGasCalculator::new)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
gasCalculator, gasLimitCalculator, true, chainId, quorumCompatibilityMode))
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
.name("ClassicTangerineWhistle");
}
@ -86,14 +83,9 @@ public class ClassicProtocolSpecs {
final Optional<BigInteger> chainId,
final OptionalInt ignoredConfigContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return tangerineWhistleDefinition(
chainId,
OptionalInt.empty(),
configStackSizeLimit,
quorumCompatibilityMode,
evmConfiguration)
chainId, OptionalInt.empty(), configStackSizeLimit, evmConfiguration)
.gasCalculator(DieHardGasCalculator::new)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_PAUSED)
.name("DieHard");
@ -104,14 +96,8 @@ public class ClassicProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return dieHardDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
quorumCompatibilityMode,
evmConfiguration)
return dieHardDefinition(chainId, contractSizeLimit, configStackSizeLimit, evmConfiguration)
.blockReward(MAX_BLOCK_REWARD)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_DELAYED)
.blockProcessorBuilder(
@ -120,7 +106,6 @@ public class ClassicProtocolSpecs {
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
goQuorumPrivacyParameters,
protocolSchedule) ->
new ClassicBlockProcessor(
transactionProcessor,
@ -138,20 +123,13 @@ public class ClassicProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return gothamDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, ecip1017EraRounds, evmConfiguration)
.difficultyCalculator(ClassicDifficultyCalculators.DIFFICULTY_BOMB_REMOVED)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
gasCalculator, gasLimitCalculator, true, chainId, quorumCompatibilityMode))
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
.name("DefuseDifficultyBomb");
}
@ -161,7 +139,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(MainnetProtocolSpecs.SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
@ -171,7 +148,6 @@ public class ClassicProtocolSpecs {
configContractSizeLimit,
configStackSizeLimit,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.evmBuilder(MainnetEVMs::byzantium)
.evmConfiguration(evmConfiguration)
@ -216,7 +192,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return atlantisDefinition(
chainId,
@ -224,7 +199,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.evmBuilder(MainnetEVMs::constantinople)
.gasCalculator(PetersburgGasCalculator::new)
@ -239,7 +213,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return aghartaDefinition(
chainId,
@ -247,7 +220,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.gasCalculator(IstanbulGasCalculator::new)
.evmBuilder(
@ -264,7 +236,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return phoenixDefinition(
chainId,
@ -272,7 +243,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.blockHeaderValidatorBuilder(
feeMarket ->
@ -311,7 +281,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return thanosDefinition(
chainId,
@ -319,7 +288,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.blockHeaderValidatorBuilder(
feeMarket ->
@ -341,7 +309,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return thanosDefinition(
chainId,
@ -349,7 +316,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.gasCalculator(BerlinGasCalculator::new)
.transactionValidatorBuilder(
@ -359,8 +325,7 @@ public class ClassicProtocolSpecs {
gasLimitCalculator,
true,
chainId,
Set.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST),
quorumCompatibilityMode))
Set.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST)))
.transactionReceiptFactory(
enableRevertReason
? MainnetProtocolSpecs::berlinTransactionReceiptFactoryWithReasonEnabled
@ -374,7 +339,6 @@ public class ClassicProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final OptionalLong ecip1017EraRounds,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(MainnetProtocolSpecs.SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
@ -384,7 +348,6 @@ public class ClassicProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration)
.gasCalculator(LondonGasCalculator::new)
.contractCreationProcessorBuilder(

@ -17,13 +17,11 @@ package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,7 +36,6 @@ public class MainnetBlockProcessor extends AbstractBlockProcessor {
final Wei blockReward,
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
final boolean skipZeroBlockRewards,
final Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
final HeaderBasedProtocolSchedule protocolSchedule) {
super(
transactionProcessor,

@ -53,7 +53,6 @@ public class MainnetProtocolSchedule {
ProtocolSpecAdapters.create(0, Function.identity()),
privacyParameters,
isRevertReasonEnabled,
config.isQuorum(),
evmConfiguration)
.createProtocolSchedule();
}

@ -28,7 +28,6 @@ public class MainnetProtocolSpecFactory {
private final OptionalInt contractSizeLimit;
private final OptionalInt evmStackSize;
private final boolean isRevertReasonEnabled;
private final boolean quorumCompatibilityMode;
private final OptionalLong ecip1017EraRounds;
private final EvmConfiguration evmConfiguration;
@ -37,106 +36,74 @@ public class MainnetProtocolSpecFactory {
final OptionalInt contractSizeLimit,
final OptionalInt evmStackSize,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final OptionalLong ecip1017EraRounds,
final EvmConfiguration evmConfiguration) {
this.chainId = chainId;
this.contractSizeLimit = contractSizeLimit;
this.evmStackSize = evmStackSize;
this.isRevertReasonEnabled = isRevertReasonEnabled;
this.quorumCompatibilityMode = quorumCompatibilityMode;
this.ecip1017EraRounds = ecip1017EraRounds;
this.evmConfiguration = evmConfiguration;
}
public ProtocolSpecBuilder frontierDefinition() {
return MainnetProtocolSpecs.frontierDefinition(
contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder homesteadDefinition() {
return MainnetProtocolSpecs.homesteadDefinition(
contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder daoRecoveryInitDefinition() {
return MainnetProtocolSpecs.daoRecoveryInitDefinition(
contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder daoRecoveryTransitionDefinition() {
return MainnetProtocolSpecs.daoRecoveryTransitionDefinition(
contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder tangerineWhistleDefinition() {
return MainnetProtocolSpecs.tangerineWhistleDefinition(
contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder spuriousDragonDefinition() {
return MainnetProtocolSpecs.spuriousDragonDefinition(
chainId, contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
chainId, contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder byzantiumDefinition() {
return MainnetProtocolSpecs.byzantiumDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder constantinopleDefinition() {
return MainnetProtocolSpecs.constantinopleDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder petersburgDefinition() {
return MainnetProtocolSpecs.petersburgDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder istanbulDefinition() {
return MainnetProtocolSpecs.istanbulDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder muirGlacierDefinition() {
return MainnetProtocolSpecs.muirGlacierDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder berlinDefinition() {
return MainnetProtocolSpecs.berlinDefinition(
chainId,
contractSizeLimit,
evmStackSize,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, isRevertReasonEnabled, evmConfiguration);
}
public ProtocolSpecBuilder londonDefinition(final GenesisConfigOptions genesisConfigOptions) {
@ -146,7 +113,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -158,7 +124,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -170,7 +135,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -181,7 +145,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -192,7 +155,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -203,7 +165,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -225,7 +186,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -247,7 +207,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration);
}
@ -256,27 +215,17 @@ public class MainnetProtocolSpecFactory {
// Classic Protocol Specs
public ProtocolSpecBuilder dieHardDefinition() {
return ClassicProtocolSpecs.dieHardDefinition(
chainId, contractSizeLimit, evmStackSize, quorumCompatibilityMode, evmConfiguration);
chainId, contractSizeLimit, evmStackSize, evmConfiguration);
}
public ProtocolSpecBuilder gothamDefinition() {
return ClassicProtocolSpecs.gothamDefinition(
chainId,
contractSizeLimit,
evmStackSize,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, ecip1017EraRounds, evmConfiguration);
}
public ProtocolSpecBuilder defuseDifficultyBombDefinition() {
return ClassicProtocolSpecs.defuseDifficultyBombDefinition(
chainId,
contractSizeLimit,
evmStackSize,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
chainId, contractSizeLimit, evmStackSize, ecip1017EraRounds, evmConfiguration);
}
public ProtocolSpecBuilder atlantisDefinition() {
@ -286,7 +235,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -297,7 +245,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -308,7 +255,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -319,7 +265,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -330,7 +275,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -341,7 +285,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
@ -352,7 +295,6 @@ public class MainnetProtocolSpecFactory {
evmStackSize,
isRevertReasonEnabled,
ecip1017EraRounds,
quorumCompatibilityMode,
evmConfiguration);
}
}

@ -29,9 +29,6 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.core.feemarket.CoinbaseFeePriceCalculator;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumBlockProcessor;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumBlockValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder.BlockProcessorBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder.BlockValidatorBuilder;
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
@ -106,7 +103,6 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder frontierDefinition(
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean goQuorumMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT);
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
@ -127,7 +123,7 @@ public abstract class MainnetProtocolSpecs {
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
gasCalculator, gasLimitCalculator, false, Optional.empty(), goQuorumMode))
gasCalculator, gasLimitCalculator, false, Optional.empty()))
.transactionProcessorBuilder(
(gasCalculator,
transactionValidator,
@ -163,8 +159,8 @@ public abstract class MainnetProtocolSpecs {
.transactionReceiptFactory(MainnetProtocolSpecs::frontierTransactionReceiptFactory)
.blockReward(FRONTIER_BLOCK_REWARD)
.skipZeroBlockRewards(false)
.blockProcessorBuilder(MainnetProtocolSpecs.blockProcessorBuilder(goQuorumMode))
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder(goQuorumMode))
.blockProcessorBuilder(MainnetBlockProcessor::new)
.blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder())
.blockImporterBuilder(MainnetBlockImporter::new)
.blockHeaderFunctions(new MainnetBlockHeaderFunctions())
.miningBeneficiaryCalculator(BlockHeader::getCoinbase)
@ -187,39 +183,18 @@ public abstract class MainnetProtocolSpecs {
}
}
public static BlockValidatorBuilder blockValidatorBuilder(final boolean goQuorumMode) {
if (goQuorumMode) {
return GoQuorumBlockValidator::new;
} else {
return (blockHeaderValidator,
blockBodyValidator,
blockProcessor,
badBlockManager,
goQuorumPrivacyParameters) ->
new MainnetBlockValidator(
blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager);
}
}
public static BlockProcessorBuilder blockProcessorBuilder(final boolean goQuorumMode) {
if (goQuorumMode) {
return GoQuorumBlockProcessor::new;
} else {
return MainnetBlockProcessor::new;
}
public static BlockValidatorBuilder blockValidatorBuilder() {
return (blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager) ->
new MainnetBlockValidator(
blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager);
}
public static ProtocolSpecBuilder homesteadDefinition(
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT);
return frontierDefinition(
configContractSizeLimit,
configStackSizeLimit,
quorumCompatibilityMode,
evmConfiguration)
return frontierDefinition(configContractSizeLimit, configStackSizeLimit, evmConfiguration)
.gasCalculator(HomesteadGasCalculator::new)
.evmBuilder(MainnetEVMs::homestead)
.contractCreationProcessorBuilder(
@ -233,11 +208,7 @@ public abstract class MainnetProtocolSpecs {
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
gasCalculator,
gasLimitCalculator,
true,
Optional.empty(),
quorumCompatibilityMode))
gasCalculator, gasLimitCalculator, true, Optional.empty()))
.difficultyCalculator(MainnetDifficultyCalculators.HOMESTEAD)
.name("Homestead");
}
@ -245,10 +216,8 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder daoRecoveryInitDefinition(
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return homesteadDefinition(
contractSizeLimit, configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
return homesteadDefinition(contractSizeLimit, configStackSizeLimit, evmConfiguration)
.blockHeaderValidatorBuilder(feeMarket -> MainnetBlockHeaderValidator.createDaoValidator())
.blockProcessorBuilder(
(transactionProcessor,
@ -256,7 +225,6 @@ public abstract class MainnetProtocolSpecs {
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
goQuorumPrivacyParameters,
protocolSchedule) ->
new DaoBlockProcessor(
new MainnetBlockProcessor(
@ -265,7 +233,6 @@ public abstract class MainnetProtocolSpecs {
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
Optional.empty(),
protocolSchedule)))
.name("DaoRecoveryInit");
}
@ -273,10 +240,8 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder daoRecoveryTransitionDefinition(
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return daoRecoveryInitDefinition(
contractSizeLimit, configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
return daoRecoveryInitDefinition(contractSizeLimit, configStackSizeLimit, evmConfiguration)
.blockProcessorBuilder(MainnetBlockProcessor::new)
.name("DaoRecoveryTransition");
}
@ -284,10 +249,8 @@ public abstract class MainnetProtocolSpecs {
public static ProtocolSpecBuilder tangerineWhistleDefinition(
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return homesteadDefinition(
contractSizeLimit, configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
return homesteadDefinition(contractSizeLimit, configStackSizeLimit, evmConfiguration)
.gasCalculator(TangerineWhistleGasCalculator::new)
.name("TangerineWhistle");
}
@ -296,14 +259,12 @@ public abstract class MainnetProtocolSpecs {
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
return tangerineWhistleDefinition(
OptionalInt.empty(), configStackSizeLimit, quorumCompatibilityMode, evmConfiguration)
return tangerineWhistleDefinition(OptionalInt.empty(), configStackSizeLimit, evmConfiguration)
.gasCalculator(SpuriousDragonGasCalculator::new)
.skipZeroBlockRewards(true)
.messageCallProcessorBuilder(
@ -323,8 +284,7 @@ public abstract class MainnetProtocolSpecs {
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
new MainnetTransactionValidator(
gasCalculator, gasLimitCalculator, true, chainId, quorumCompatibilityMode))
new MainnetTransactionValidator(gasCalculator, gasLimitCalculator, true, chainId))
.transactionProcessorBuilder(
(gasCalculator,
transactionValidator,
@ -348,15 +308,10 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
return spuriousDragonDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, evmConfiguration)
.gasCalculator(ByzantiumGasCalculator::new)
.evmBuilder(MainnetEVMs::byzantium)
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium)
@ -387,15 +342,9 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return byzantiumDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason, evmConfiguration)
.difficultyCalculator(MainnetDifficultyCalculators.CONSTANTINOPLE)
.gasCalculator(ConstantinopleGasCalculator::new)
.evmBuilder(MainnetEVMs::constantinople)
@ -408,15 +357,9 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return constantinopleDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason, evmConfiguration)
.gasCalculator(PetersburgGasCalculator::new)
.name("Petersburg");
}
@ -426,7 +369,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
@ -435,7 +377,6 @@ public abstract class MainnetProtocolSpecs {
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
.gasCalculator(IstanbulGasCalculator::new)
.evmBuilder(
@ -460,15 +401,9 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return istanbulDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason, evmConfiguration)
.difficultyCalculator(MainnetDifficultyCalculators.MUIR_GLACIER)
.name("MuirGlacier");
}
@ -478,15 +413,9 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt contractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return muirGlacierDefinition(
chainId,
contractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason, evmConfiguration)
.gasCalculator(BerlinGasCalculator::new)
.transactionValidatorBuilder(
(gasCalculator, gasLimitCalculator) ->
@ -495,8 +424,7 @@ public abstract class MainnetProtocolSpecs {
gasLimitCalculator,
true,
chainId,
Set.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST),
quorumCompatibilityMode))
Set.of(TransactionType.FRONTIER, TransactionType.ACCESS_LIST)))
.transactionReceiptFactory(
enableRevertReason
? MainnetProtocolSpecs::berlinTransactionReceiptFactoryWithReasonEnabled
@ -510,7 +438,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
@ -526,7 +453,6 @@ public abstract class MainnetProtocolSpecs {
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode,
evmConfiguration)
.gasCalculator(LondonGasCalculator::new)
.gasLimitCalculator(
@ -543,7 +469,6 @@ public abstract class MainnetProtocolSpecs {
TransactionType.FRONTIER,
TransactionType.ACCESS_LIST,
TransactionType.EIP1559),
quorumCompatibilityMode,
Integer.MAX_VALUE))
.transactionProcessorBuilder(
(gasCalculator,
@ -590,7 +515,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return londonDefinition(
chainId,
@ -598,7 +522,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.difficultyCalculator(MainnetDifficultyCalculators.ARROW_GLACIER)
.name("ArrowGlacier");
@ -610,7 +533,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return arrowGlacierDefinition(
chainId,
@ -618,7 +540,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.difficultyCalculator(MainnetDifficultyCalculators.GRAY_GLACIER)
.name("GrayGlacier");
@ -630,7 +551,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return grayGlacierDefinition(
@ -639,7 +559,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
@ -657,7 +576,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
// extra variables need to support flipping the warm coinbase flag.
@ -674,7 +592,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
// gas calculator has new code to support EIP-3860 limit and meter initcode
.gasCalculator(ShanghaiGasCalculator::new)
@ -712,7 +629,6 @@ public abstract class MainnetProtocolSpecs {
TransactionType.FRONTIER,
TransactionType.ACCESS_LIST,
TransactionType.EIP1559),
quorumCompatibilityMode,
SHANGHAI_INIT_CODE_SIZE_LIMIT))
.withdrawalsProcessor(new WithdrawalsProcessor())
.withdrawalsValidator(new WithdrawalsValidator.AllowedWithdrawals())
@ -725,7 +641,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
@ -746,7 +661,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.feeMarket(cancunFeeMarket)
// gas calculator for EIP-4844 data gas
@ -799,7 +713,6 @@ public abstract class MainnetProtocolSpecs {
TransactionType.ACCESS_LIST,
TransactionType.EIP1559,
TransactionType.BLOB),
quorumCompatibilityMode,
SHANGHAI_INIT_CODE_SIZE_LIMIT))
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::cancun)
.name("Cancun");
@ -811,7 +724,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return cancunDefinition(
@ -820,7 +732,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->
@ -835,7 +746,6 @@ public abstract class MainnetProtocolSpecs {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
return futureEipsDefinition(
@ -844,7 +754,6 @@ public abstract class MainnetProtocolSpecs {
configStackSizeLimit,
enableRevertReason,
genesisConfigOptions,
quorumCompatibilityMode,
evmConfiguration)
.evmBuilder(
(gasCalculator, jdCacheConfig) ->

@ -31,7 +31,6 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.worldstate.GoQuorumMutablePrivateWorldStateUpdater;
import org.hyperledger.besu.evm.AccessListEntry;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.EvmAccount;
@ -446,32 +445,30 @@ public class MainnetTransactionProcessor {
final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas();
if (!worldState.getClass().equals(GoQuorumMutablePrivateWorldStateUpdater.class)) {
// if this is not a private GoQuorum transaction we have to update the coinbase
final var coinbase = worldState.getOrCreate(miningBeneficiary).getMutable();
final long usedGas = transaction.getGasLimit() - refundedGas;
final CoinbaseFeePriceCalculator coinbaseCalculator;
if (blockHeader.getBaseFee().isPresent()) {
final Wei baseFee = blockHeader.getBaseFee().get();
if (transactionGasPrice.compareTo(baseFee) < 0) {
return TransactionProcessingResult.failed(
gasUsedByTransaction,
refundedGas,
ValidationResult.invalid(
TransactionInvalidReason.TRANSACTION_PRICE_TOO_LOW,
"transaction price must be greater than base fee"),
Optional.empty());
}
coinbaseCalculator = coinbaseFeePriceCalculator;
} else {
coinbaseCalculator = CoinbaseFeePriceCalculator.frontier();
// update the coinbase
final var coinbase = worldState.getOrCreate(miningBeneficiary).getMutable();
final long usedGas = transaction.getGasLimit() - refundedGas;
final CoinbaseFeePriceCalculator coinbaseCalculator;
if (blockHeader.getBaseFee().isPresent()) {
final Wei baseFee = blockHeader.getBaseFee().get();
if (transactionGasPrice.compareTo(baseFee) < 0) {
return TransactionProcessingResult.failed(
gasUsedByTransaction,
refundedGas,
ValidationResult.invalid(
TransactionInvalidReason.TRANSACTION_PRICE_TOO_LOW,
"transaction price must be greater than base fee"),
Optional.empty());
}
coinbaseCalculator = coinbaseFeePriceCalculator;
} else {
coinbaseCalculator = CoinbaseFeePriceCalculator.frontier();
}
final Wei coinbaseWeiDelta =
coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee());
final Wei coinbaseWeiDelta =
coinbaseCalculator.price(usedGas, transactionGasPrice, blockHeader.getBaseFee());
coinbase.incrementBalance(coinbaseWeiDelta);
}
coinbase.incrementBalance(coinbaseWeiDelta);
initialFrame.getSelfDestructs().forEach(worldState::deleteAccount);

@ -51,7 +51,6 @@ public class MainnetTransactionValidator {
private Optional<TransactionFilter> transactionFilter = Optional.empty();
private final Set<TransactionType> acceptedTransactionTypes;
private final boolean goQuorumCompatibilityMode;
private final int maxInitcodeSize;
@ -59,15 +58,13 @@ public class MainnetTransactionValidator {
final GasCalculator gasCalculator,
final GasLimitCalculator gasLimitCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId,
final boolean goQuorumCompatibilityMode) {
final Optional<BigInteger> chainId) {
this(
gasCalculator,
gasLimitCalculator,
checkSignatureMalleability,
chainId,
Set.of(TransactionType.FRONTIER),
goQuorumCompatibilityMode);
Set.of(TransactionType.FRONTIER));
}
public MainnetTransactionValidator(
@ -75,8 +72,7 @@ public class MainnetTransactionValidator {
final GasLimitCalculator gasLimitCalculator,
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId,
final Set<TransactionType> acceptedTransactionTypes,
final boolean quorumCompatibilityMode) {
final Set<TransactionType> acceptedTransactionTypes) {
this(
gasCalculator,
gasLimitCalculator,
@ -84,7 +80,6 @@ public class MainnetTransactionValidator {
checkSignatureMalleability,
chainId,
acceptedTransactionTypes,
quorumCompatibilityMode,
Integer.MAX_VALUE);
}
@ -95,7 +90,6 @@ public class MainnetTransactionValidator {
final boolean checkSignatureMalleability,
final Optional<BigInteger> chainId,
final Set<TransactionType> acceptedTransactionTypes,
final boolean goQuorumCompatibilityMode,
final int maxInitcodeSize) {
this.gasCalculator = gasCalculator;
this.gasLimitCalculator = gasLimitCalculator;
@ -103,7 +97,6 @@ public class MainnetTransactionValidator {
this.disallowSignatureMalleability = checkSignatureMalleability;
this.chainId = chainId;
this.acceptedTransactionTypes = acceptedTransactionTypes;
this.goQuorumCompatibilityMode = goQuorumCompatibilityMode;
this.maxInitcodeSize = maxInitcodeSize;
}
@ -157,12 +150,6 @@ public class MainnetTransactionValidator {
final Optional<Wei> maybeBaseFee,
final TransactionValidationParams transactionValidationParams) {
if (goQuorumCompatibilityMode && transaction.hasCostParams()) {
return ValidationResult.invalid(
TransactionInvalidReason.GAS_PRICE_MUST_BE_ZERO,
"gasPrice must be set to zero on a GoQuorum compatible network");
}
if (maybeBaseFee.isPresent()) {
final Wei price = feeMarket.getTransactionPriceCalculator().price(transaction, maybeBaseFee);
if (!transactionValidationParams.isAllowMaxFeeGasBelowBaseFee()
@ -284,9 +271,7 @@ public class MainnetTransactionValidator {
transaction.getChainId().get(), chainId.get()));
}
if (!transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)
&& chainId.isEmpty()
&& transaction.getChainId().isPresent()) {
if (chainId.isEmpty() && transaction.getChainId().isPresent()) {
return ValidationResult.invalid(
TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED,
"replay protected signatures is not supported");
@ -356,8 +341,4 @@ public class MainnetTransactionValidator {
ImmutableTransactionValidationParams.builder().isAllowFutureNonce(allowFutureNonce).build();
return validateForSender(transaction, sender, validationParams);
}
public boolean getGoQuorumCompatibilityMode() {
return goQuorumCompatibilityMode;
}
}

@ -36,7 +36,6 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
final ProtocolSpecAdapters protocolSpecAdapters,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
this(
config,
@ -44,7 +43,6 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
protocolSpecAdapters,
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
}
@ -53,7 +51,6 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
final ProtocolSpecAdapters protocolSpecAdapters,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
this(
config,
@ -61,7 +58,6 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
protocolSpecAdapters,
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
}
@ -71,15 +67,8 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
final ProtocolSpecAdapters protocolSpecAdapters,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
super(
config,
protocolSpecAdapters,
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
super(config, protocolSpecAdapters, privacyParameters, isRevertReasonEnabled, evmConfiguration);
this.defaultChainId = defaultChainId;
}
@ -225,10 +214,7 @@ public class ProtocolScheduleBuilder extends AbstractProtocolScheduleBuilder {
protocolSchedule,
classicBlockNumber,
ClassicProtocolSpecs.classicRecoveryInitDefinition(
config.getContractSizeLimit(),
config.getEvmStackSize(),
quorumCompatibilityMode,
evmConfiguration),
config.getContractSizeLimit(), config.getEvmStackSize(), evmConfiguration),
Function.identity());
protocolSchedule.putMilestone(classicBlockNumber + 1, originalProtocolSpec);
});

@ -25,7 +25,6 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.chain.BadBlockManager;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.core.BlockImporter;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.ethereum.mainnet.precompiles.privacy.FlexiblePrivacyPrecompiledContract;
@ -346,11 +345,7 @@ public class ProtocolSpecBuilder {
final BlockValidator blockValidator =
blockValidatorBuilder.apply(
blockHeaderValidator,
blockBodyValidator,
blockProcessor,
badBlockManager,
privacyParameters.getGoQuorumPrivacyParameters());
blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager);
final BlockImporter blockImporter = blockImporterBuilder.apply(blockValidator);
return new ProtocolSpec(
name,
@ -426,7 +421,6 @@ public class ProtocolSpecBuilder {
blockReward,
miningBeneficiaryCalculator,
skipZeroBlockRewards,
privacyParameters.getGoQuorumPrivacyParameters(),
protocolSchedule);
}
@ -465,7 +459,6 @@ public class ProtocolSpecBuilder {
Wei blockReward,
MiningBeneficiaryCalculator miningBeneficiaryCalculator,
boolean skipZeroBlockRewards,
Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters,
HeaderBasedProtocolSchedule protocolSchedule);
}
@ -474,8 +467,7 @@ public class ProtocolSpecBuilder {
BlockHeaderValidator blockHeaderValidator,
BlockBodyValidator blockBodyValidator,
BlockProcessor blockProcessor,
BadBlockManager badBlockManager,
Optional<GoQuorumPrivacyParameters> goQuorumPrivacyParameters);
BadBlockManager badBlockManager);
}
public interface BlockImporterBuilder {

@ -33,15 +33,8 @@ public class TimestampScheduleBuilder extends AbstractProtocolScheduleBuilder {
final ProtocolSpecAdapters protocolSpecAdapters,
final PrivacyParameters privacyParameters,
final boolean isRevertReasonEnabled,
final boolean quorumCompatibilityMode,
final EvmConfiguration evmConfiguration) {
super(
config,
protocolSpecAdapters,
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
super(config, protocolSpecAdapters, privacyParameters, isRevertReasonEnabled, evmConfiguration);
this.defaultChainId = Optional.of(defaultChainId);
}

@ -1,52 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.privacy;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class GoQuorumSendRawTxArgs {
private final String privateFrom;
private final List<String> privateFor;
private final int privacyFlag;
@JsonCreator
public GoQuorumSendRawTxArgs(
@JsonProperty("privateFrom") final String privateFrom,
@JsonProperty("privateFor") final List<String> privateFor,
@JsonProperty("privacyFlag") final int privacyFlag) {
this.privateFrom = privateFrom;
this.privateFor = privateFor;
this.privacyFlag = privacyFlag;
}
public String getPrivateFrom() {
return privateFrom;
}
public List<String> getPrivateFor() {
return privateFor;
}
public int getPrivacyFlag() {
return privacyFlag;
}
}

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.storage;
import org.hyperledger.besu.ethereum.chain.BlockchainStorage;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStorage;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
@ -38,12 +37,6 @@ public interface StorageProvider extends Closeable {
SnappableKeyValueStorage getSnappableStorageBySegmentIdentifier(SegmentIdentifier segment);
WorldStateStorage createPrivateWorldStateStorage();
WorldStatePreimageStorage createPrivateWorldStatePreimageStorage();
GoQuorumPrivateStorage createGoQuorumPrivateStorage();
boolean isWorldStateIterable();
boolean isWorldStateSnappable();

@ -1,72 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.storage.keyvalue;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public class GoQuorumKeyValueStoragePrefixedKeyBlockchainStorage
extends KeyValueStoragePrefixedKeyBlockchainStorage {
private static final Bytes BLOCK_HEADER_PRIVATE_BLOOM_PREFIX = Bytes.of(8);
public GoQuorumKeyValueStoragePrefixedKeyBlockchainStorage(
final KeyValueStorage storage, final BlockHeaderFunctions blockHeaderFunctions) {
super(storage, blockHeaderFunctions);
}
@Override
public Optional<BlockHeader> getBlockHeader(final Hash blockHash) {
final Optional<BlockHeader> blockHeaderOptional =
get(BLOCK_HEADER_PREFIX, blockHash)
.map(b -> BlockHeader.readFrom(RLP.input(b), blockHeaderFunctions));
if (blockHeaderOptional.isPresent()) {
final Optional<Bytes> privateBloomBytesOptional =
get(BLOCK_HEADER_PRIVATE_BLOOM_PREFIX, blockHash);
privateBloomBytesOptional.ifPresent(
pBB -> blockHeaderOptional.get().setPrivateLogsBloom(new LogsBloomFilter(pBB)));
}
return blockHeaderOptional;
}
@Override
public Updater updater() {
return new Updater(storage.startTransaction());
}
public static class Updater extends KeyValueStoragePrefixedKeyBlockchainStorage.Updater {
private Updater(final KeyValueStorageTransaction transaction) {
super(transaction);
}
@Override
public void putBlockHeader(final Hash blockHash, final BlockHeader blockHeader) {
set(BLOCK_HEADER_PREFIX, blockHash, RLP.encode(blockHeader::writeTo));
blockHeader
.getPrivateLogsBloom()
.ifPresent(privateLoom -> set(BLOCK_HEADER_PRIVATE_BLOOM_PREFIX, blockHash, privateLoom));
}
}
}

@ -1,57 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.storage.keyvalue;
import org.hyperledger.besu.ethereum.chain.BlockchainStorage;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import java.util.function.Function;
public class GoQuorumKeyValueStorageProvider extends KeyValueStorageProvider {
public GoQuorumKeyValueStorageProvider(
final Function<SegmentIdentifier, KeyValueStorage> storageCreator,
final KeyValueStorage worldStatePreimageStorage,
final boolean segmentIsolationSupported,
final ObservableMetricsSystem metricsSystem) {
super(storageCreator, worldStatePreimageStorage, segmentIsolationSupported, metricsSystem);
}
public GoQuorumKeyValueStorageProvider(
final Function<SegmentIdentifier, KeyValueStorage> storageCreator,
final KeyValueStorage worldStatePreimageStorage,
final KeyValueStorage privateWorldStatePreimageStorage,
final boolean segmentIsolationSupported,
final ObservableMetricsSystem metricsSystem) {
super(
storageCreator,
worldStatePreimageStorage,
privateWorldStatePreimageStorage,
segmentIsolationSupported,
SNAPSHOT_ISOLATION_UNSUPPORTED,
metricsSystem);
}
@Override
public BlockchainStorage createBlockchainStorage(final ProtocolSchedule protocolSchedule) {
return new GoQuorumKeyValueStoragePrefixedKeyBlockchainStorage(
getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.BLOCKCHAIN),
ScheduleBasedBlockHeaderFunctions.create(protocolSchedule));
}
}

@ -29,8 +29,9 @@ public enum KeyValueSegmentIdentifier implements SegmentIdentifier {
ACCOUNT_STORAGE_STORAGE(new byte[] {8}, new int[] {2}),
TRIE_BRANCH_STORAGE(new byte[] {9}, new int[] {2}),
TRIE_LOG_STORAGE(new byte[] {10}, new int[] {2}),
GOQUORUM_PRIVATE_WORLD_STATE(new byte[] {11}),
GOQUORUM_PRIVATE_STORAGE(new byte[] {12}),
// previously supported GoQuorum private states
// GOQUORUM_PRIVATE_WORLD_STATE(new byte[] {11}),
// GOQUORUM_PRIVATE_STORAGE(new byte[] {12}),
BACKWARD_SYNC_HEADERS(new byte[] {13}),
BACKWARD_SYNC_BLOCKS(new byte[] {14}),
BACKWARD_SYNC_CHAIN(new byte[] {15}),

@ -16,8 +16,6 @@ package org.hyperledger.besu.ethereum.storage.keyvalue;
import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.chain.BlockchainStorage;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateKeyValueStorage;
import org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStorage;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
@ -41,7 +39,6 @@ public class KeyValueStorageProvider implements StorageProvider {
protected final Function<SegmentIdentifier, KeyValueStorage> storageCreator;
private final KeyValueStorage worldStatePreimageStorage;
private final KeyValueStorage privateWorldStatePreimageStorage;
private final boolean isWorldStateIterable;
private final boolean isWorldStateSnappable;
protected final Map<SegmentIdentifier, KeyValueStorage> storageInstances = new HashMap<>();
@ -54,7 +51,6 @@ public class KeyValueStorageProvider implements StorageProvider {
final ObservableMetricsSystem metricsSystem) {
this.storageCreator = storageCreator;
this.worldStatePreimageStorage = worldStatePreimageStorage;
this.privateWorldStatePreimageStorage = null;
this.isWorldStateIterable = segmentIsolationSupported;
this.isWorldStateSnappable = SNAPSHOT_ISOLATION_UNSUPPORTED;
this.metricsSystem = metricsSystem;
@ -63,13 +59,11 @@ public class KeyValueStorageProvider implements StorageProvider {
public KeyValueStorageProvider(
final Function<SegmentIdentifier, KeyValueStorage> storageCreator,
final KeyValueStorage worldStatePreimageStorage,
final KeyValueStorage privateWorldStatePreimageStorage,
final boolean segmentIsolationSupported,
final boolean storageSnapshotIsolationSupported,
final ObservableMetricsSystem metricsSystem) {
this.storageCreator = storageCreator;
this.worldStatePreimageStorage = worldStatePreimageStorage;
this.privateWorldStatePreimageStorage = privateWorldStatePreimageStorage;
this.isWorldStateIterable = segmentIsolationSupported;
this.isWorldStateSnappable = storageSnapshotIsolationSupported;
this.metricsSystem = metricsSystem;
@ -108,23 +102,6 @@ public class KeyValueStorageProvider implements StorageProvider {
return (SnappableKeyValueStorage) getStorageBySegmentIdentifier(segment);
}
@Override
public WorldStateStorage createPrivateWorldStateStorage() {
return new WorldStateKeyValueStorage(
getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.GOQUORUM_PRIVATE_WORLD_STATE));
}
@Override
public WorldStatePreimageStorage createPrivateWorldStatePreimageStorage() {
return new WorldStatePreimageKeyValueStorage(privateWorldStatePreimageStorage);
}
@Override
public GoQuorumPrivateStorage createGoQuorumPrivateStorage() {
return new GoQuorumPrivateKeyValueStorage(
getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.GOQUORUM_PRIVATE_STORAGE));
}
@Override
public boolean isWorldStateIterable() {
return isWorldStateIterable;

@ -30,7 +30,6 @@ public class KeyValueStorageProviderBuilder {
private KeyValueStorageFactory storageFactory;
private BesuConfiguration commonConfiguration;
private MetricsSystem metricsSystem;
private boolean isGoQuorumCompatibilityMode;
public KeyValueStorageProviderBuilder withStorageFactory(
final KeyValueStorageFactory storageFactory) {
@ -49,12 +48,6 @@ public class KeyValueStorageProviderBuilder {
return this;
}
public KeyValueStorageProviderBuilder isGoQuorumCompatibilityMode(
final boolean isGoQuorumCompatibilityMode) {
this.isGoQuorumCompatibilityMode = isGoQuorumCompatibilityMode;
return this;
}
public KeyValueStorageProvider build() {
checkNotNull(storageFactory, "Cannot build a storage provider without a storage factory.");
checkNotNull(
@ -65,26 +58,13 @@ public class KeyValueStorageProviderBuilder {
final KeyValueStorage worldStatePreImageStorage =
new LimitedInMemoryKeyValueStorage(DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE);
final KeyValueStorage privateWorldStatePreImageStorage =
new LimitedInMemoryKeyValueStorage(DEFAULT_WORLD_STATE_PRE_IMAGE_CACHE_SIZE);
// this tickles init needed for isSegmentIsolationSupported
storageFactory.create(KeyValueSegmentIdentifier.BLOCKCHAIN, commonConfiguration, metricsSystem);
if (isGoQuorumCompatibilityMode) {
return new GoQuorumKeyValueStorageProvider(
segment -> storageFactory.create(segment, commonConfiguration, metricsSystem),
worldStatePreImageStorage,
privateWorldStatePreImageStorage,
storageFactory.isSegmentIsolationSupported(),
(ObservableMetricsSystem) metricsSystem);
} else {
return new KeyValueStorageProvider(
segment -> storageFactory.create(segment, commonConfiguration, metricsSystem),
worldStatePreImageStorage,
privateWorldStatePreImageStorage,
storageFactory.isSegmentIsolationSupported(),
storageFactory.isSnapshotIsolationSupported(),
(ObservableMetricsSystem) metricsSystem);
}
return new KeyValueStorageProvider(
segment -> storageFactory.create(segment, commonConfiguration, metricsSystem),
worldStatePreImageStorage,
storageFactory.isSegmentIsolationSupported(),
storageFactory.isSnapshotIsolationSupported(),
(ObservableMetricsSystem) metricsSystem);
}
}

@ -1,34 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.transaction;
import static org.hyperledger.besu.ethereum.core.Transaction.GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MAX;
import static org.hyperledger.besu.ethereum.core.Transaction.GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MIN;
import java.math.BigInteger;
public class GoQuorumPrivateTransactionDetector {
/**
* Returns whether or not <i>v</i> indicates a GoQuorum private transaction.
*
* @param v the v value of a transaction
* @return true if GoQuorum private transaction, false otherwise
*/
public static final boolean isGoQuorumPrivateTransactionV(final BigInteger v) {
return ((v.compareTo(GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MAX) <= 0)
&& (v.compareTo(GO_QUORUM_PRIVATE_TRANSACTION_V_VALUE_MIN)) >= 0);
}
}

@ -14,8 +14,6 @@
*/
package org.hyperledger.besu.ethereum.transaction;
import static org.hyperledger.besu.ethereum.goquorum.GoQuorumPrivateStateUtil.getPrivateWorldStateAtBlock;
import org.hyperledger.besu.crypto.SECPSignature;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
@ -27,7 +25,6 @@ import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
@ -36,7 +33,6 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
import org.hyperledger.besu.ethereum.worldstate.GoQuorumMutablePrivateAndPublicWorldStateUpdater;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.tracing.OperationTracer;
@ -77,7 +73,6 @@ public class TransactionSimulator {
private final Blockchain blockchain;
private final WorldStateArchive worldStateArchive;
private final ProtocolSchedule protocolSchedule;
private final Optional<PrivacyParameters> maybePrivacyParameters;
public TransactionSimulator(
final Blockchain blockchain,
@ -86,18 +81,6 @@ public class TransactionSimulator {
this.blockchain = blockchain;
this.worldStateArchive = worldStateArchive;
this.protocolSchedule = protocolSchedule;
this.maybePrivacyParameters = Optional.empty();
}
public TransactionSimulator(
final Blockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final PrivacyParameters privacyParameters) {
this.blockchain = blockchain;
this.worldStateArchive = worldStateArchive;
this.protocolSchedule = protocolSchedule;
this.maybePrivacyParameters = Optional.of(privacyParameters);
}
public Optional<TransactionSimulatorResult> process(
@ -245,29 +228,6 @@ public class TransactionSimulator {
operationTracer,
dataGasPrice);
// If GoQuorum privacy enabled, and value = zero, get max gas possible for a PMT hash.
// It is possible to have a data field that has a lower intrinsic value than the PMT hash.
// This means a potential over-estimate of gas, but the tx, if sent with this gas, will not
// fail.
final boolean goQuorumCompatibilityMode =
transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode();
if (goQuorumCompatibilityMode && value.isZero()) {
final long privateGasEstimateAndState =
protocolSpec.getGasCalculator().getMaximumTransactionCost(64);
if (privateGasEstimateAndState > result.getEstimateGasUsedByTransaction()) {
// modify the result to have the larger estimate
final TransactionProcessingResult resultPmt =
TransactionProcessingResult.successful(
result.getLogs(),
privateGasEstimateAndState,
result.getGasRemaining(),
result.getOutput(),
result.getValidationResult());
return Optional.of(new TransactionSimulatorResult(transaction, resultPmt));
}
}
return Optional.of(new TransactionSimulatorResult(transaction, result));
}
@ -325,20 +285,8 @@ public class TransactionSimulator {
return Optional.ofNullable(transaction);
}
// return combined private/public world state updater if GoQuorum mode, otherwise the public state
public WorldUpdater getEffectiveWorldStateUpdater(
final BlockHeader header, final MutableWorldState publicWorldState) {
if (maybePrivacyParameters.isPresent()
&& maybePrivacyParameters.get().getGoQuorumPrivacyParameters().isPresent()) {
final MutableWorldState privateWorldState =
getPrivateWorldStateAtBlock(
maybePrivacyParameters.get().getGoQuorumPrivacyParameters(), header);
return new GoQuorumMutablePrivateAndPublicWorldStateUpdater(
publicWorldState.updater(), privateWorldState.updater());
}
return publicWorldState.updater();
}

@ -1,53 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.worldstate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
// This class uses a public WorldUpdater and a private WorldUpdater to
// provide a MutableWorldStateUpdater that can read and write from
// BOTH the private world state and the public world state.
//
// Note that only writes to private states are committed to the
// underlying storage (via
// DefaultMutablePrivateWorldStateUpdater::commit) whereas public
// state changes are discarded.
//
// World state obtained by this class must not be persisted: it allows
// illegal write access from private to public contract data that
// would result in world state divergence between nodes.
public class GoQuorumMutablePrivateAndPublicWorldStateUpdater
extends GoQuorumMutablePrivateWorldStateUpdater {
public GoQuorumMutablePrivateAndPublicWorldStateUpdater(
final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) {
super(publicWorldUpdater, privateWorldUpdater);
}
@Override
public EvmAccount getAccount(final Address address) {
final EvmAccount privateAccount = privateWorldUpdater.getAccount(address);
if (privateAccount != null && !privateAccount.isEmpty()) {
return privateAccount;
}
final EvmAccount publicAccount = publicWorldUpdater.getAccount(address);
if (publicAccount != null && !publicAccount.isEmpty()) {
return publicAccount;
}
return privateAccount;
}
}

@ -1,48 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.worldstate;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.worldstate.UpdateTrackingAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
// This class uses a public WorldUpdater and a private WorldUpdater to provide a
// MutableWorldStateUpdater that can read and write from the private world state and can read from
// the public world state, but cannot write to it.
public class GoQuorumMutablePrivateWorldStateUpdater
extends DefaultMutablePrivateWorldStateUpdater {
public GoQuorumMutablePrivateWorldStateUpdater(
final WorldUpdater publicWorldUpdater, final WorldUpdater privateWorldUpdater) {
super(publicWorldUpdater, privateWorldUpdater);
}
@Override
public EvmAccount getOrCreateSenderAccount(final Address address) {
return new UpdateTrackingAccount<>(publicWorldUpdater.getOrCreate(address));
}
@Override
public EvmAccount getSenderAccount(final MessageFrame frame) {
final Address senderAddress = frame.getSenderAddress();
if (senderAddress.equals(frame.getOriginatorAddress())) {
return new UpdateTrackingAccount<>(publicWorldUpdater.getOrCreate(senderAddress));
} else {
return getAccount(senderAddress);
}
}
}

@ -121,7 +121,6 @@ public class ExecutionContextTestFixture {
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
genesisConfigFile.getConfigOptions().isQuorum(),
EvmConfiguration.DEFAULT)
.createProtocolSchedule();
}

@ -38,7 +38,6 @@ public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider {
super(
segmentIdentifier -> new InMemoryKeyValueStorage(),
new InMemoryKeyValueStorage(),
new InMemoryKeyValueStorage(),
SEGMENT_ISOLATION_SUPPORTED,
SNAPSHOT_ISOLATION_UNSUPPORTED,
new NoOpMetricsSystem());

@ -72,7 +72,6 @@ public class BlockImportExceptionHandlingTest {
Wei.ZERO,
BlockHeader::getCoinbase,
true,
Optional.empty(),
protocolSchedule);
private final BlockHeaderValidator blockHeaderValidator = mock(BlockHeaderValidator.class);
private final BlockBodyValidator blockBodyValidator = mock(BlockBodyValidator.class);

@ -1,89 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.core;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.encoding.TransactionDecoder;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import java.math.BigInteger;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Test;
public class TransactionGoQuorumTest {
private static final RLPInput ETHEREUM_PUBLIC_TX_RLP =
toRLP(
"0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884");
private static final RLPInput GOQUORUM_PRIVATE_TX_RLP_V37 =
toRLP(
"0xf88d0b808347b7608080b840290a80a37d198ff06abe189b638ff53ac8a8dc51a0aff07609d2aa75342783ae493b3e3c6b564c0eebe49284b05a0726fb33087b9e0231d349ea0c7b5661c8c525a07144db7045a395e608cda6ab051c86cc4fb42e319960b82087f3b26f0cbc3c2da00223ac129b22aec7a6c2ace3c3ef39c5eaaa54070fd82d8ee2140b0e70b1dca9");
private static final RLPInput GOQUORUM_PRIVATE_TX_RLP_V38 =
toRLP(
"0xf88d0b808347b7608080b840290a80a37d198ff06abe189b638ff53ac8a8dc51a0aff07609d2aa75342783ae493b3e3c6b564c0eebe49284b05a0726fb33087b9e0231d349ea0c7b5661c8c526a07144db7045a395e608cda6ab051c86cc4fb42e319960b82087f3b26f0cbc3c2da00223ac129b22aec7a6c2ace3c3ef39c5eaaa54070fd82d8ee2140b0e70b1dca9");
private static final boolean goQuorumCompatibilityMode = true;
@Test
public void givenPublicTransaction_assertThatIsGoQuorumFlagIsFalse() {
final Transaction transaction =
TransactionDecoder.decodeForWire(ETHEREUM_PUBLIC_TX_RLP, goQuorumCompatibilityMode);
assertThat(transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)).isFalse();
assertThat(transaction.hasCostParams()).isTrue();
}
@Test
public void givenGoQuorumTransactionV37_assertThatIsGoQuorumFlagIsTrue() {
final Transaction transaction =
TransactionDecoder.decodeForWire(GOQUORUM_PRIVATE_TX_RLP_V37, goQuorumCompatibilityMode);
assertThat(transaction.getV()).isEqualTo(37);
assertThat(transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)).isTrue();
assertThat(transaction.hasCostParams()).isFalse();
}
@Test
public void givenGoQuorumTransactionV38_assertThatIsGoQuorumFlagIsTrue() {
final Transaction transaction =
TransactionDecoder.decodeForWire(GOQUORUM_PRIVATE_TX_RLP_V38, goQuorumCompatibilityMode);
assertThat(transaction.getV()).isEqualTo(38);
assertThat(transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)).isTrue();
assertThat(transaction.hasCostParams()).isFalse();
}
@Test
public void givenTransactionWithChainId_assertThatIsGoQuorumFlagIsFalse() {
final Transaction transaction =
Transaction.builder().chainId(BigInteger.valueOf(0)).gasPrice(Wei.ZERO).build();
assertThat(transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)).isFalse();
}
@Test
public void givenTransactionWithoutChainIdAndV37_assertThatIsGoQuorumFlagIsTrue() {
final Transaction transaction =
Transaction.builder().v(BigInteger.valueOf(37)).gasPrice(Wei.ZERO).build();
assertThat(transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)).isTrue();
}
private static RLPInput toRLP(final String bytes) {
return RLP.input(Bytes.fromHexString(bytes));
}
}

@ -18,12 +18,10 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.evm.account.Account.MAX_NONCE;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPException;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import java.math.BigInteger;
import java.util.Arrays;
@ -40,24 +38,9 @@ class TransactionDecoderTest {
"0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884";
private static final String EIP1559_TX_RLP =
"0xb8a902f8a686796f6c6f7632800285012a05f20082753094000000000000000000000000000000000000aaaa8080f838f794000000000000000000000000000000000000aaaae1a0000000000000000000000000000000000000000000000000000000000000000001a00c1d69648e348fe26155b45de45004f0e4195f6352d8f0935bc93e98a3e2a862a060064e5b9765c0ac74223b0cf49635c59ae0faf82044fd17bcc68a549ade6f95";
private static final String GOQUORUM_PRIVATE_TX_RLP =
"0xf88d0b808347b7608080b840290a80a37d198ff06abe189b638ff53ac8a8dc51a0aff07609d2aa75342783ae493b3e3c6b564c0eebe49284b05a0726fb33087b9e0231d349ea0c7b5661c8c526a07144db7045a395e608cda6ab051c86cc4fb42e319960b82087f3b26f0cbc3c2da00223ac129b22aec7a6c2ace3c3ef39c5eaaa54070fd82d8ee2140b0e70b1dca9";
private static final String NONCE_64_BIT_MAX_MINUS_2_TX_RLP =
"0xf86788fffffffffffffffe0182520894095e7baea6a6c7c4c2dfeb977efac326af552d8780801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804";
@Test
void decodeGoQuorumPrivateTransactionRlp() {
final boolean goQuorumCompatibilityMode = true;
final RLPInput input = RLP.input(Bytes.fromHexString(GOQUORUM_PRIVATE_TX_RLP));
final Transaction transaction =
TransactionDecoder.decodeForWire(input, goQuorumCompatibilityMode);
assertThat(transaction).isNotNull();
assertThat(transaction.getV()).isEqualTo(38);
assertThat(transaction.getSender())
.isEqualByComparingTo(Address.fromHexString("0xed9d02e382b34818e88b88a309c7fe71e65f419d"));
}
@Test
void decodeFrontierNominalCase() {
final Transaction transaction =
@ -81,11 +64,8 @@ class TransactionDecoderTest {
void doesNotDecodeEIP1559WithLargeMaxFeePerGasOrLargeMaxPriorityFeePerGas() {
final String txWithBigFees =
"0x02f84e0101a1648a5f8b2dcad5ea5ba6b720ff069c1d87c21a4a6a5b3766b39e2c2792367bb066a1ffa5ffaf5b0560d3a9fb186c2ede2ae6751bc0b4fef9107cf36389630b6196a38805800180c0010203";
final boolean goQuorumCompatibilityMode = false;
assertThatThrownBy(
() ->
TransactionDecoder.decodeOpaqueBytes(
Bytes.fromHexString(txWithBigFees), goQuorumCompatibilityMode))
() -> TransactionDecoder.decodeOpaqueBytes(Bytes.fromHexString(txWithBigFees)))
.isInstanceOf(RLPException.class);
}
@ -103,7 +83,6 @@ class TransactionDecoderTest {
new Object[][] {
{FRONTIER_TX_RLP, "FRONTIER_TX_RLP"},
{EIP1559_TX_RLP, "EIP1559_TX_RLP"},
{GOQUORUM_PRIVATE_TX_RLP, "GOQUORUM_PRIVATE_TX_RLP"},
{NONCE_64_BIT_MAX_MINUS_2_TX_RLP, "NONCE_64_BIT_MAX_MINUS_2_TX_RLP"}
});
}

@ -1,165 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.goquorum;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.EnclaveServerException;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.GoQuorumPrivacyParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState;
import java.util.Collections;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class GoQuorumBlockProcessorTest {
@Mock private AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory;
@Mock private GoQuorumEnclave goQuorumEnclave;
@Mock private GoQuorumPrivateStorage goQuorumPrivateStorage;
@Mock private MainnetTransactionProcessor transactionProcessor;
@Mock private MainnetTransactionValidator transactionValidator;
@Mock private HeaderBasedProtocolSchedule protocolSchedule;
@Mock private ProtocolSpec protocolSpec;
private GoQuorumPrivacyParameters goQuorumPrivacyParameters;
@Before
public void setup() {
when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec);
goQuorumPrivacyParameters =
new GoQuorumPrivacyParameters(goQuorumEnclave, "123", goQuorumPrivateStorage, null);
}
@Test
public void noAccountCreatedWhenBlockRewardIsZeroAndSkipped() {
final Blockchain blockchain = new ReferenceTestBlockchain();
final GoQuorumBlockProcessor blockProcessor =
new GoQuorumBlockProcessor(
transactionProcessor,
transactionReceiptFactory,
Wei.ZERO,
BlockHeader::getCoinbase,
true,
Optional.of(goQuorumPrivacyParameters),
protocolSchedule);
final MutableWorldState worldState = ReferenceTestWorldState.create(emptyMap());
final Hash initialHash = worldState.rootHash();
final BlockHeader emptyBlockHeader =
new BlockHeaderTestFixture()
.transactionsRoot(Hash.EMPTY_LIST_HASH)
.ommersHash(Hash.EMPTY_LIST_HASH)
.buildHeader();
blockProcessor.processBlock(blockchain, worldState, emptyBlockHeader, emptyList(), emptyList());
// An empty block with 0 reward should not change the world state
assertThat(worldState.rootHash()).isEqualTo(initialHash);
}
@Test
public void accountCreatedWhenBlockRewardIsZeroAndNotSkipped() {
final Blockchain blockchain = new ReferenceTestBlockchain();
final GoQuorumBlockProcessor blockProcessor =
new GoQuorumBlockProcessor(
transactionProcessor,
transactionReceiptFactory,
Wei.ZERO,
BlockHeader::getCoinbase,
false,
Optional.of(goQuorumPrivacyParameters),
protocolSchedule);
final MutableWorldState worldState = ReferenceTestWorldState.create(emptyMap());
final Hash initialHash = worldState.rootHash();
final BlockHeader emptyBlockHeader =
new BlockHeaderTestFixture()
.transactionsRoot(Hash.EMPTY_LIST_HASH)
.ommersHash(Hash.EMPTY_LIST_HASH)
.buildHeader();
blockProcessor.processBlock(blockchain, worldState, emptyBlockHeader, emptyList(), emptyList());
// An empty block with 0 reward should change the world state prior to EIP158
assertThat(worldState.rootHash()).isNotEqualTo(initialHash);
}
@Test
public void enclaveNotAvailable() {
final Blockchain blockchain = new ReferenceTestBlockchain();
final GoQuorumBlockProcessor blockProcessor =
new GoQuorumBlockProcessor(
transactionProcessor,
transactionReceiptFactory,
Wei.ZERO,
BlockHeader::getCoinbase,
false,
Optional.of(goQuorumPrivacyParameters),
protocolSchedule);
final MutableWorldState worldState = ReferenceTestWorldState.create(emptyMap());
final Block block = mock(Block.class);
final BlockHeader blockHeader = mock(BlockHeader.class);
final BlockBody blockBody = mock(BlockBody.class);
final Transaction transaction = mock(Transaction.class);
when(transaction.getGasLimit()).thenReturn(1000L);
when(transaction.isGoQuorumPrivateTransaction(true)).thenReturn(true);
when(transaction.getPayload()).thenReturn(Bytes.wrap(new byte[] {(byte) 1}));
when(block.getBody()).thenReturn(blockBody);
when(blockBody.getTransactions()).thenReturn(Collections.singletonList(transaction));
when(blockBody.getOmmers()).thenReturn(Collections.emptyList());
when(blockHeader.getNumber()).thenReturn(20000L);
when(blockHeader.getGasLimit()).thenReturn(20000L);
when(block.getHeader()).thenReturn(blockHeader);
when(goQuorumEnclave.receive(any())).thenThrow(new EnclaveServerException(1, "a"));
when(transactionProcessor.getTransactionValidator()).thenReturn(transactionValidator);
when(transactionValidator.getGoQuorumCompatibilityMode()).thenReturn(true);
assertThatThrownBy(() -> blockProcessor.processBlock(blockchain, worldState, worldState, block))
.isExactlyInstanceOf(EnclaveServerException.class)
.hasMessageContaining("a");
}
}

@ -52,7 +52,6 @@ public class DefaultTimestampScheduleTest {
config = new StubGenesisConfigOptions();
config.chainId(chainId);
boolean isRevertReasonEnabled = false;
boolean quorumCompatibilityMode = false;
builder =
new TimestampScheduleBuilder(
config,
@ -60,7 +59,6 @@ public class DefaultTimestampScheduleTest {
ProtocolSpecAdapters.create(FIRST_TIMESTAMP_FORK, modifier),
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
}
@ -82,7 +80,6 @@ public class DefaultTimestampScheduleTest {
ProtocolSpecAdapters.create(2L, modifier),
privacyParameters,
false,
false,
evmConfiguration);
final TimestampSchedule schedule = builder.createTimestampSchedule();

@ -30,8 +30,6 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestBlockchain;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -63,7 +61,6 @@ public class MainnetBlockProcessorTest extends AbstractBlockProcessorTest {
Wei.ZERO,
BlockHeader::getCoinbase,
true,
Optional.empty(),
protocolSchedule);
final MutableWorldState worldState = ReferenceTestWorldState.create(emptyMap());
@ -90,7 +87,6 @@ public class MainnetBlockProcessorTest extends AbstractBlockProcessorTest {
Wei.ZERO,
BlockHeader::getCoinbase,
false,
Optional.empty(),
protocolSchedule);
final MutableWorldState worldState = ReferenceTestWorldState.create(emptyMap());

@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum.mainnet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_MUST_BE_ZERO;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.INVALID_TRANSACTION_FORMAT;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.MAX_PRIORITY_FEE_PER_GAS_EXCEEDS_MAX_FEE_PER_GAS;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE;
@ -73,17 +72,11 @@ public class MainnetTransactionValidatorTest {
.chainId(Optional.of(BigInteger.ONE))
.createTransaction(senderKeys);
private final boolean defaultGoQuorumCompatibilityMode = false;
@Test
public void shouldRejectTransactionIfIntrinsicGasExceedsGasLimit() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
final Transaction transaction =
new TransactionTestFixture()
.gasLimit(10)
@ -100,11 +93,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenTransactionHasChainIdAndValidatorDoesNot() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
assertThat(validator.validate(basicTransaction, Optional.empty(), transactionValidationParams))
.isEqualTo(
ValidationResult.invalid(
@ -118,8 +107,7 @@ public class MainnetTransactionValidatorTest {
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.valueOf(2)),
defaultGoQuorumCompatibilityMode);
Optional.of(BigInteger.valueOf(2)));
assertThat(validator.validate(basicTransaction, Optional.empty(), transactionValidationParams))
.isEqualTo(ValidationResult.invalid(TransactionInvalidReason.WRONG_CHAIN_ID));
}
@ -128,11 +116,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenSenderAccountDoesNotExist() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
assertThat(validator.validateForSender(basicTransaction, null, false))
.isEqualTo(ValidationResult.invalid(TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE));
}
@ -141,11 +125,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenTransactionNonceBelowAccountNonce() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
final Account account = accountWithNonce(basicTransaction.getNonce() + 1);
assertThat(validator.validateForSender(basicTransaction, account, false))
@ -157,11 +137,7 @@ public class MainnetTransactionValidatorTest {
shouldRejectTransactionWhenTransactionNonceAboveAccountNonceAndFutureNonceIsNotAllowed() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
final Account account = accountWithNonce(basicTransaction.getNonce() - 1);
assertThat(validator.validateForSender(basicTransaction, account, false))
@ -173,11 +149,7 @@ public class MainnetTransactionValidatorTest {
shouldAcceptTransactionWhenTransactionNonceAboveAccountNonceAndFutureNonceIsAllowed() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
final Account account = accountWithNonce(basicTransaction.getNonce() - 1);
assertThat(validator.validateForSender(basicTransaction, account, true))
@ -188,11 +160,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWhenNonceExceedsMaximumAllowedNonce() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
final Transaction transaction =
new TransactionTestFixture().nonce(11).createTransaction(senderKeys);
@ -206,11 +174,7 @@ public class MainnetTransactionValidatorTest {
public void transactionWithNullSenderCanBeValidIfGasPriceAndValueIsZero() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.of(BigInteger.ONE),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.of(BigInteger.ONE));
final TransactionTestFixture builder = new TransactionTestFixture();
final KeyPair senderKeyPair = SIGNATURE_ALGORITHM.get().generateKeyPair();
@ -225,11 +189,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionIfAccountIsNotEOA() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter(false));
Account invalidEOA =
@ -246,11 +206,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionIfAccountIsNotPermitted() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter(false));
assertThat(validator.validateForSender(basicTransaction, accountWithNonce(0), true))
@ -261,11 +217,7 @@ public class MainnetTransactionValidatorTest {
public void shouldAcceptValidTransactionIfAccountIsPermitted() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter(true));
assertThat(validator.validateForSender(basicTransaction, accountWithNonce(0), true))
@ -276,11 +228,7 @@ public class MainnetTransactionValidatorTest {
public void shouldRejectTransactionWithMaxFeeTimesGasLimitGreaterThanBalance() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter(true));
assertThat(
@ -314,7 +262,6 @@ public class MainnetTransactionValidatorTest {
new TransactionType[] {
TransactionType.FRONTIER, TransactionType.ACCESS_LIST, TransactionType.EIP1559
}),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
validator.setTransactionFilter(transactionFilter(true));
@ -354,11 +301,7 @@ public class MainnetTransactionValidatorTest {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter);
final TransactionValidationParams validationParams =
@ -376,11 +319,7 @@ public class MainnetTransactionValidatorTest {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator,
GasLimitCalculator.constant(),
false,
Optional.empty(),
defaultGoQuorumCompatibilityMode);
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty());
validator.setTransactionFilter(transactionFilter);
final TransactionValidationParams validationParams =
@ -407,7 +346,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final MainnetTransactionValidator eip1559Validator =
@ -418,7 +356,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final Transaction transaction =
@ -452,7 +389,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final Transaction transaction =
new TransactionTestFixture()
@ -477,7 +413,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final Transaction transaction =
new TransactionTestFixture()
@ -501,7 +436,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final Transaction transaction =
new TransactionTestFixture()
@ -527,7 +461,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
Integer.MAX_VALUE);
final Transaction transaction =
new TransactionTestFixture()
@ -554,7 +487,6 @@ public class MainnetTransactionValidatorTest {
false,
Optional.of(BigInteger.ONE),
Set.of(TransactionType.FRONTIER, TransactionType.EIP1559),
defaultGoQuorumCompatibilityMode,
0xc000);
var bigPayload =
@ -572,49 +504,6 @@ public class MainnetTransactionValidatorTest {
.isEqualTo("Initcode size of 49153 exceeds maximum size of 49152");
}
@Test
public void goQuorumCompatibilityModeRejectNonZeroGasPrice() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty(), true);
final Transaction transaction =
new TransactionTestFixture()
.gasPrice(Wei.ONE)
.chainId(Optional.empty())
.createTransaction(senderKeys);
assertThat(
validator
.validate(transaction, Optional.empty(), transactionValidationParams)
.isValid())
.isFalse();
assertThat(
validator
.validate(transaction, Optional.empty(), transactionValidationParams)
.getInvalidReason())
.isEqualTo(GAS_PRICE_MUST_BE_ZERO);
}
@Test
public void goQuorumCompatibilityModeSuccessZeroGasPrice() {
final MainnetTransactionValidator validator =
new MainnetTransactionValidator(
gasCalculator, GasLimitCalculator.constant(), false, Optional.empty(), true);
final Transaction transaction =
new TransactionTestFixture()
.gasPrice(Wei.ZERO)
.chainId(Optional.empty())
.createTransaction(senderKeys);
when(gasCalculator.transactionIntrinsicGasCost(any(), anyBoolean())).thenReturn(50L);
assertThat(
validator
.validate(transaction, Optional.empty(), transactionValidationParams)
.isValid())
.isTrue();
}
private Account accountWithNonce(final long nonce) {
return account(basicTransaction.getUpfrontCost(0L), nonce);
}

@ -53,7 +53,6 @@ public class MutableProtocolScheduleTest {
config = new StubGenesisConfigOptions();
config.chainId(DEFAULT_CHAIN_ID);
boolean isRevertReasonEnabled = false;
boolean quorumCompatibilityMode = false;
builder =
new ProtocolScheduleBuilder(
config,
@ -61,7 +60,6 @@ public class MutableProtocolScheduleTest {
ProtocolSpecAdapters.create(FIRST_TIMESTAMP_FORK, modifier),
new PrivacyParameters(),
isRevertReasonEnabled,
quorumCompatibilityMode,
EvmConfiguration.DEFAULT);
}

@ -56,7 +56,6 @@ public class ProtocolScheduleBuilderTest {
ProtocolSpecAdapters.create(0, Function.identity()),
new PrivacyParameters(),
false,
false,
EvmConfiguration.DEFAULT);
}
@ -166,7 +165,6 @@ public class ProtocolScheduleBuilderTest {
ProtocolSpecAdapters.create(blockNumber, modifier),
new PrivacyParameters(),
false,
false,
EvmConfiguration.DEFAULT);
return new BlockNumberStreamingProtocolSchedule(

@ -45,7 +45,6 @@ public class TimestampScheduleBuilderTest {
config = new StubGenesisConfigOptions();
config.chainId(chainId);
boolean isRevertReasonEnabled = false;
boolean quorumCompatibilityMode = false;
builder =
new TimestampScheduleBuilder(
config,
@ -53,7 +52,6 @@ public class TimestampScheduleBuilderTest {
ProtocolSpecAdapters.create(FIRST_TIMESTAMP_FORK, modifier),
privacyParameters,
isRevertReasonEnabled,
quorumCompatibilityMode,
evmConfiguration);
}

@ -37,7 +37,6 @@ import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
@ -82,7 +81,6 @@ public class TransactionSimulatorTest {
@Mock private ProtocolSchedule protocolSchedule;
@Mock private ProtocolSpec protocolSpec;
@Mock private MainnetTransactionProcessor transactionProcessor;
@Mock private MainnetTransactionValidator transactionValidator;
private final BlockHeaderTestFixture blockHeaderTestFixture = new BlockHeaderTestFixture();
@ -90,9 +88,6 @@ public class TransactionSimulatorTest {
public void setUp() {
this.transactionSimulator =
new TransactionSimulator(blockchain, worldStateArchive, protocolSchedule);
when(transactionProcessor.getTransactionValidator()).thenReturn(transactionValidator);
when(transactionValidator.getGoQuorumCompatibilityMode()).thenReturn(false);
}
@Test

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.eth.transactions;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedStatus.ADDED;
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedStatus.ALREADY_KNOWN;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_NOT_AVAILABLE;
@ -355,15 +354,6 @@ public class TransactionPool implements BlockAddedObserver {
private TransactionInvalidReason validatePrice(
final Transaction transaction, final boolean isLocal, final FeeMarket feeMarket) {
// Check whether it's a GoQuorum transaction
boolean goQuorumCompatibilityMode = getTransactionValidator().getGoQuorumCompatibilityMode();
if (transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)) {
final Optional<Wei> weiValue = ofNullable(transaction.getValue());
if (weiValue.isPresent() && !weiValue.get().isZero()) {
return TransactionInvalidReason.ETHER_VALUE_NOT_SUPPORTED;
}
}
if (isLocal) {
if (!configuration.getTxFeeCap().isZero()
&& getMaxGasPrice(transaction).get().greaterThan(configuration.getTxFeeCap())) {

@ -259,7 +259,6 @@ public class MessageWrapperTest {
recIdAndChainId(Byte.decode(v)).getKey()),
Bytes.fromHexString(data),
recIdAndChainId(Byte.decode(v)).getValue(),
Optional.empty(),
Optional.empty());
}
}

@ -28,7 +28,6 @@ import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@ -346,7 +345,6 @@ public abstract class AbstractTransactionPoolTest {
transactionPool.addRemoteTransactions(singletonList(transaction));
assertTransactionNotPending(transaction);
verify(transactionValidator).getGoQuorumCompatibilityMode();
verifyNoMoreInteractions(transactionValidator);
}
@ -380,7 +378,6 @@ public abstract class AbstractTransactionPoolTest {
.validateForSender(eq(transaction1), eq(null), any(TransactionValidationParams.class));
verify(transactionValidator).validate(eq(transaction2), any(Optional.class), any());
verify(transactionValidator).validateForSender(eq(transaction2), any(), any());
verify(transactionValidator, atLeastOnce()).getGoQuorumCompatibilityMode();
verifyNoMoreInteractions(transactionValidator);
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save