diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfiguration.java index c8c88d4e5..7317b5fb4 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfiguration.java @@ -67,8 +67,10 @@ public class SignerConfiguration { private final Optional bellatrixForkEpoch; private final Optional capellaForkEpoch; + private final Optional denebForkEpoch; private final Optional network; private final boolean keyManagerApiEnabled; + private final Optional trustedSetup; private Optional watermarkRepairParameters; private int downstreamHttpPort; private Optional downstreamTlsOptions; @@ -111,12 +113,14 @@ public SignerConfiguration( final Optional altairForkEpoch, final Optional bellatrixForkEpoch, final Optional capellaForkEpoch, + final Optional denebForkEpoch, final Optional network, final boolean keyManagerApiEnabled, final Optional watermarkRepairParameters, final int downstreamHttpPort, final Optional downstreamTlsOptions, - final ChainIdProvider chainIdProvider) { + final ChainIdProvider chainIdProvider, + final Optional trustedSetup) { this.hostname = hostname; this.logLevel = logLevel; this.httpRpcPort = httpRpcPort; @@ -152,12 +156,14 @@ public SignerConfiguration( this.altairForkEpoch = altairForkEpoch; this.bellatrixForkEpoch = bellatrixForkEpoch; this.capellaForkEpoch = capellaForkEpoch; + this.denebForkEpoch = denebForkEpoch; this.network = network; this.keyManagerApiEnabled = keyManagerApiEnabled; this.watermarkRepairParameters = watermarkRepairParameters; this.downstreamHttpPort = downstreamHttpPort; this.downstreamTlsOptions = downstreamTlsOptions; this.chainIdProvider = chainIdProvider; + this.trustedSetup = trustedSetup; } public String hostname() { @@ -300,6 +306,10 @@ public Optional getCapellaForkEpoch() { return capellaForkEpoch; } + public Optional getDenebForkEpoch() { + return denebForkEpoch; + } + public Optional getNetwork() { return network; } @@ -331,4 +341,8 @@ public Optional getDownstreamTlsOptions() { public ChainIdProvider getChainIdProvider() { return chainIdProvider; } + + public Optional getTrustedSetup() { + return trustedSetup; + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfigurationBuilder.java index bcb21e1a3..dc78a259b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/SignerConfigurationBuilder.java @@ -69,6 +69,7 @@ public class SignerConfigurationBuilder { private Long altairForkEpoch = null; private Long bellatrixForkEpoch = null; private Long capellaForkEpoch = null; + private Long denebForkEpoch = null; private String network = null; private boolean keyManagerApiEnabled = false; private KeystoresParameters keystoresParameters; @@ -77,6 +78,7 @@ public class SignerConfigurationBuilder { private ClientTlsOptions downstreamTlsOptions; private ChainIdProvider chainIdProvider = new ConfigurationChainId(DEFAULT_CHAIN_ID); + private String trustedSetup; public SignerConfigurationBuilder withLogLevel(final Level logLevel) { this.logLevel = logLevel; @@ -255,6 +257,11 @@ public SignerConfigurationBuilder withCapellaForkEpoch(final long capellaForkEpo return this; } + public SignerConfigurationBuilder withDenebForkEpoch(final long denebForkEpoch) { + this.denebForkEpoch = denebForkEpoch; + return this; + } + public SignerConfigurationBuilder withNetwork(final String network) { this.network = network; return this; @@ -297,6 +304,11 @@ public SignerConfigurationBuilder withChainIdProvider(final ChainIdProvider chai return this; } + public SignerConfigurationBuilder withTrustedSetup(final String trustedSetup) { + this.trustedSetup = trustedSetup; + return this; + } + public SignerConfiguration build() { if (mode == null) { throw new IllegalArgumentException("Mode cannot be null"); @@ -337,11 +349,13 @@ public SignerConfiguration build() { Optional.ofNullable(altairForkEpoch), Optional.ofNullable(bellatrixForkEpoch), Optional.ofNullable(capellaForkEpoch), + Optional.ofNullable(denebForkEpoch), Optional.ofNullable(network), keyManagerApiEnabled, Optional.ofNullable(watermarkRepairParameters), downstreamHttpPort, Optional.ofNullable(downstreamTlsOptions), - chainIdProvider); + chainIdProvider, + Optional.ofNullable(trustedSetup)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsConfigFileImpl.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsConfigFileImpl.java index a00ffc94d..9fd805734 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsConfigFileImpl.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsConfigFileImpl.java @@ -419,6 +419,20 @@ private String createEth2SlashingProtectionArgs() { signerConfig.getCapellaForkEpoch().get())); } + if (signerConfig.getDenebForkEpoch().isPresent()) { + yamlConfig.append( + String.format( + YAML_NUMERIC_FMT, + "eth2.Xnetwork-deneb-fork-epoch", + signerConfig.getDenebForkEpoch().get())); + } + + if (signerConfig.getTrustedSetup().isPresent()) { + yamlConfig.append( + String.format( + YAML_STRING_FMT, "eth2.Xtrusted-setup", signerConfig.getTrustedSetup().get())); + } + if (signerConfig.getNetwork().isPresent()) { yamlConfig.append( String.format(YAML_STRING_FMT, "eth2.network", signerConfig.getNetwork().get())); diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsDefaultImpl.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsDefaultImpl.java index 90c9e29ea..42762aa00 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsDefaultImpl.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/signer/runner/CmdLineParamsDefaultImpl.java @@ -253,6 +253,16 @@ private Collection createEth2Args() { params.add(Long.toString(signerConfig.getCapellaForkEpoch().get())); } + if (signerConfig.getDenebForkEpoch().isPresent()) { + params.add("--Xnetwork-deneb-fork-epoch"); + params.add(Long.toString(signerConfig.getDenebForkEpoch().get())); + } + + if (signerConfig.getTrustedSetup().isPresent()) { + params.add("--Xtrusted-setup"); + params.add(signerConfig.getTrustedSetup().get()); + } + if (signerConfig.getNetwork().isPresent()) { params.add("--network"); params.add(signerConfig.getNetwork().get()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/DataStructureUtilAdapter.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/DataStructureUtilAdapter.java index a5c87dd3c..8b181171a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/DataStructureUtilAdapter.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/DataStructureUtilAdapter.java @@ -135,7 +135,8 @@ private ExecutionPayload randomExecutionPayload(final SpecVersion specVersion) { .blockHash(util.randomBytes32()) .transactions(util.randomExecutionPayloadTransactions()) .withdrawals(() -> randomExecutionPayloadWithdrawals(specVersion)) - .excessBlobGas(util::randomUInt64)); + .excessBlobGas(util::randomUInt64) + .blobGasUsed(util::randomUInt64)); } private List randomExecutionPayloadWithdrawals(final SpecVersion specVersion) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/Eth2BlockSigningRequestUtil.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/Eth2BlockSigningRequestUtil.java index 6ca218c62..c2c9d987d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/Eth2BlockSigningRequestUtil.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/dsl/utils/Eth2BlockSigningRequestUtil.java @@ -75,6 +75,7 @@ public Eth2SigningRequestBody createBlockV2Request() { return createBlockV2Request(new BlockRequest(specMilestone, getBeaconBlock())); case BELLATRIX: case CAPELLA: + case DENEB: return createBlockV2Request(new BlockRequest(specMilestone, getBeaconBlockHeader())); default: throw new IllegalStateException( diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2BlockSigningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2BlockSigningAcceptanceTest.java index 0ac580595..3b524e965 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2BlockSigningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2BlockSigningAcceptanceTest.java @@ -59,7 +59,7 @@ void setup() { @ParameterizedTest(name = "#{index} - Sign and verify BlockV2 Signature for spec {0}") @EnumSource( value = SpecMilestone.class, - names = {"PHASE0", "ALTAIR", "BELLATRIX", "CAPELLA"}) + names = {"PHASE0", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}) void signAndVerifyBlockV2Signature(final SpecMilestone specMilestone) throws Exception { final Eth2BlockSigningRequestUtil util = new Eth2BlockSigningRequestUtil(specMilestone); @@ -92,7 +92,7 @@ void signAndVerifyLegacyBlockSignature() throws Exception { name = "#{index} - Empty block request for spec {0} should return bad request status") @EnumSource( value = SpecMilestone.class, - names = {"PHASE0", "ALTAIR", "BELLATRIX", "CAPELLA"}) + names = {"PHASE0", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}) void emptyBlockRequestReturnsBadRequestStatus(final SpecMilestone specMilestone) throws JsonProcessingException { final Eth2BlockSigningRequestUtil util = new Eth2BlockSigningRequestUtil(specMilestone); diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2CustomNetworkFileAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2CustomNetworkFileAcceptanceTest.java index a216ddc41..53829369e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2CustomNetworkFileAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/Eth2CustomNetworkFileAcceptanceTest.java @@ -19,16 +19,19 @@ import tech.pegasys.teku.bls.BLSPublicKey; import tech.pegasys.teku.bls.BLSSecretKey; import tech.pegasys.teku.infrastructure.unsigned.UInt64; +import tech.pegasys.teku.networks.Eth2NetworkConfiguration; import tech.pegasys.teku.spec.Spec; import tech.pegasys.teku.spec.SpecFactory; import tech.pegasys.teku.spec.datastructures.util.ForkAndSpecMilestone; import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SigningRequestBody; +import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder; import tech.pegasys.web3signer.dsl.utils.Eth2BlockSigningRequestUtil; import tech.pegasys.web3signer.dsl.utils.MetadataFileHelpers; import tech.pegasys.web3signer.signing.KeyType; import java.nio.file.Path; import java.util.List; +import java.util.Objects; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.io.Resources; @@ -50,6 +53,10 @@ public class Eth2CustomNetworkFileAcceptanceTest extends SigningAcceptanceTestBa BLSSecretKey.fromBytes(Bytes32.fromHexString(PRIVATE_KEY)); private static final BLSKeyPair KEY_PAIR = new BLSKeyPair(KEY); private static final BLSPublicKey PUBLIC_KEY = KEY_PAIR.getPublicKey(); + private static final String TRUSTED_SETUP_PATH = + Objects.requireNonNull( + Eth2NetworkConfiguration.class.getResource("minimal-trusted-setup.txt")) + .toExternalForm(); @BeforeEach void setup() { @@ -57,14 +64,25 @@ void setup() { final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml"); METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS); - setupEth2SignerWithCustomNetworkConfig(NETWORK_CONFIG_PATH); + final SignerConfigurationBuilder builder = new SignerConfigurationBuilder(); + builder + .withKeyStoreDirectory(testDirectory) + .withMode("eth2") + .withNetwork(NETWORK_CONFIG_PATH) + .withTrustedSetup(TRUSTED_SETUP_PATH); + startSigner(builder.build()); } @Test void signAndVerifyBlockV2SignatureForAllEnabledMilestones() throws Exception { - final Spec spec = SpecFactory.create(NETWORK_CONFIG_PATH.toString()); + final Spec spec = + SpecFactory.create( + NETWORK_CONFIG_PATH.toString(), + specConfigBuilder -> + specConfigBuilder.denebBuilder( + denebBuilder -> denebBuilder.trustedSetupPath(TRUSTED_SETUP_PATH))); final List enabledMilestones = spec.getEnabledMilestones(); - assertThat(enabledMilestones.size()).isEqualTo(4); + assertThat(enabledMilestones.size()).isEqualTo(5); for (final ForkAndSpecMilestone forkAndSpecMilestone : enabledMilestones) { final Eth2SigningRequestBody request = diff --git a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/SigningAcceptanceTestBase.java b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/SigningAcceptanceTestBase.java index a3e02fc7e..7ed27f78d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/SigningAcceptanceTestBase.java +++ b/acceptance-tests/src/test/java/tech/pegasys/web3signer/tests/signing/SigningAcceptanceTestBase.java @@ -55,6 +55,15 @@ protected void setupEth2Signer(final Eth2Network eth2Network, final SpecMileston startSigner(builder.build()); } + protected void setupEth2Signer(final Path networkConfigFile, final SpecMilestone specMilestone) { + final SignerConfigurationBuilder builder = new SignerConfigurationBuilder(); + builder.withKeyStoreDirectory(testDirectory).withMode("eth2").withNetwork(networkConfigFile); + + setForkEpochs(specMilestone, builder); + + startSigner(builder.build()); + } + protected void setupEth2SignerWithCustomNetworkConfig(final Path networkConfigFile) { final SignerConfigurationBuilder builder = new SignerConfigurationBuilder(); builder.withKeyStoreDirectory(testDirectory).withMode("eth2").withNetwork(networkConfigFile); @@ -84,6 +93,12 @@ private void setForkEpochs( builder.withBellatrixForkEpoch(0L); builder.withCapellaForkEpoch(0L); break; + case DENEB: + builder.withAltairForkEpoch(0L); + builder.withBellatrixForkEpoch(0L); + builder.withCapellaForkEpoch(0L); + builder.withDenebForkEpoch(0L); + break; default: throw new IllegalStateException( "Setting manual fork epoch is not yet implemented for " + specMilestone); diff --git a/acceptance-tests/src/test/resources/eth2/network_config.yaml b/acceptance-tests/src/test/resources/eth2/network_config.yaml index 7670724db..c5fff184a 100644 --- a/acceptance-tests/src/test/resources/eth2/network_config.yaml +++ b/acceptance-tests/src/test/resources/eth2/network_config.yaml @@ -57,6 +57,8 @@ BELLATRIX_FORK_EPOCH: 8 BELLATRIX_FORK_VERSION: 0x020000fd CAPELLA_FORK_EPOCH: 10 CAPELLA_FORK_VERSION: 0x030000fd +DENEB_FORK_VERSION: 0x04000001 +DENEB_FORK_EPOCH: 12 SHARDING_FORK_EPOCH: 18446744073709551615 SHARDING_FORK_VERSION: 0x030000fd INACTIVITY_SCORE_BIAS: 4 diff --git a/commandline/src/main/java/tech/pegasys/web3signer/commandline/subcommands/Eth2SubCommand.java b/commandline/src/main/java/tech/pegasys/web3signer/commandline/subcommands/Eth2SubCommand.java index 2e5303f32..f54e57b08 100644 --- a/commandline/src/main/java/tech/pegasys/web3signer/commandline/subcommands/Eth2SubCommand.java +++ b/commandline/src/main/java/tech/pegasys/web3signer/commandline/subcommands/Eth2SubCommand.java @@ -116,6 +116,24 @@ private static class NetworkCliCompletionCandidates extends ArrayList { converter = UInt64Converter.class) private UInt64 capellaForkEpoch; + @CommandLine.Option( + names = {"--Xnetwork-deneb-fork-epoch"}, + hidden = true, + paramLabel = "", + description = "Override the Deneb fork activation epoch.", + arity = "1", + converter = UInt64Converter.class) + private UInt64 denebForkEpoch; + + @CommandLine.Option( + names = {"--Xtrusted-setup"}, + hidden = true, + paramLabel = "", + description = + "The trusted setup which is needed for KZG commitments. Only required when creating a custom network. This value should be a file or URL pointing to a trusted setup.", + arity = "1") + private String trustedSetup = null; // Depends on network configuration + @CommandLine.Option( names = {"--key-manager-api-enabled", "--enable-key-manager-api"}, paramLabel = "", @@ -182,6 +200,12 @@ private Eth2NetworkConfiguration createEth2NetworkConfig() { if (capellaForkEpoch != null) { builder.capellaForkEpoch(capellaForkEpoch); } + if (denebForkEpoch != null) { + builder.denebForkEpoch(denebForkEpoch); + } + if (trustedSetup != null) { + builder.trustedSetup(trustedSetup); + } return builder.build(); } diff --git a/core/src/main/resources/openapi-specs/eth2/signing/schemas.yaml b/core/src/main/resources/openapi-specs/eth2/signing/schemas.yaml index 27f643105..6cb8b97ca 100644 --- a/core/src/main/resources/openapi-specs/eth2/signing/schemas.yaml +++ b/core/src/main/resources/openapi-specs/eth2/signing/schemas.yaml @@ -489,6 +489,7 @@ components: - $ref: '#/components/schemas/BlockRequestAltair' - $ref: '#/components/schemas/BlockRequestBellatrix' - $ref: '#/components/schemas/BlockRequestCapella' + - $ref: '#/components/schemas/BlockRequestDeneb' discriminator: propertyName: version mapping: @@ -496,6 +497,7 @@ components: ALTAIR: '#/components/schemas/BlockRequestAltair' BELLATRIX: '#/components/schemas/BlockRequestBellatrix' CAPELLA: '#/components/schemas/BlockRequestCapella' + DENEB: '#/components/schemas/BlockRequestDeneb' required: - beacon_block BlockRequestPhase0: @@ -550,6 +552,19 @@ components: required: - version - block_header + BlockRequestDeneb: + type: object + properties: + version: + type: string + enum: + - DENEB + description: 'version to identify block request type.' + block_header: + $ref: "#/components/schemas/BeaconBlockHeader" + required: + - version + - block_header BeaconBlockAltair: type: "object" properties: