Skip to content

Commit

Permalink
[Bellatrix]: Use block_header instead of block for block signing requ…
Browse files Browse the repository at this point in the history
…ests (BLOCK_V2) (#547)
  • Loading branch information
usmansaleem committed May 10, 2022
1 parent 88ed990 commit 8fe4798
Show file tree
Hide file tree
Showing 23 changed files with 255 additions and 97 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

## 22.5.0
### Breaking Changes
- ETH2 Mode - block signing request (BLOCK_V2), starting from BELLATRIX fork, use block_header instead of block. [#547](https://github.com/ConsenSys/web3signer/pull/547)

### Features Added
- Added support for optimized block signing requests starting from Bellatrix fork. [#437](https://github.com/ConsenSys/web3signer/issues/437)
- Early access: Support for Gnosis network in Eth2 mode. `--network gnosis`

### Bugs Fixed
- Keys loaded using the AWS secrets manager with environment config didn't work when using web identity tokens due to missing sts library.
Expand Down
2 changes: 2 additions & 0 deletions acceptance-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ dependencies {
testImplementation 'tech.pegasys.teku.internal:core'
testImplementation 'tech.pegasys.teku.internal:spec'
testImplementation 'tech.pegasys.teku.internal:networks'
testImplementation 'tech.pegasys.teku.internal:json'
testImplementation 'tech.pegasys.teku.internal:jackson'
testImplementation (group: 'tech.pegasys.teku.internal', name: 'spec', classifier: 'test-fixtures')
testImplementation (group: 'tech.pegasys.teku.internal', name: 'bls', classifier: 'test-fixtures')
testImplementation 'tech.pegasys.teku.internal:serializer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class SignerConfiguration {
private final long slashingPruningSlotsPerEpoch;
private final long slashingPruningInterval;
private final Optional<Long> altairForkEpoch;

private final Optional<Long> bellatrixForkEpoch;
private final Optional<String> network;
private final boolean keyManagerApiEnabled;

Expand Down Expand Up @@ -90,6 +92,7 @@ public SignerConfiguration(
final boolean useConfigFile,
final Optional<Path> slashingDbPoolConfigurationFile,
final Optional<Long> altairForkEpoch,
final Optional<Long> bellatrixForkEpoch,
final Optional<String> network,
final boolean keyManagerApiEnabled) {
this.hostname = hostname;
Expand Down Expand Up @@ -121,6 +124,7 @@ public SignerConfiguration(
this.useConfigFile = useConfigFile;
this.slashingProtectionDbPoolConfigurationFile = slashingDbPoolConfigurationFile;
this.altairForkEpoch = altairForkEpoch;
this.bellatrixForkEpoch = bellatrixForkEpoch;
this.network = network;
this.keyManagerApiEnabled = keyManagerApiEnabled;
}
Expand Down Expand Up @@ -249,6 +253,10 @@ public Optional<Long> getAltairForkEpoch() {
return altairForkEpoch;
}

public Optional<Long> getBellatrixForkEpoch() {
return bellatrixForkEpoch;
}

public Optional<String> getNetwork() {
return network;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class SignerConfigurationBuilder {
private long slashingPruningSlotsPerEpoch = 1;
private long slashingPruningInterval = 1;
private Long altairForkEpoch = null;
private Long bellatrixForkEpoch = null;
private String network = null;
private boolean keyManagerApiEnabled = false;

Expand Down Expand Up @@ -211,6 +212,11 @@ public SignerConfigurationBuilder withAltairForkEpoch(final long altairForkEpoch
return this;
}

public SignerConfigurationBuilder withBellatrixForkEpoch(final long bellatrixForkEpoch) {
this.bellatrixForkEpoch = bellatrixForkEpoch;
return this;
}

public SignerConfigurationBuilder withNetwork(final String network) {
this.network = network;
return this;
Expand Down Expand Up @@ -255,6 +261,7 @@ public SignerConfiguration build() {
useConfigFile,
Optional.ofNullable(slashingProtectionDbPoolConfigurationFile),
Optional.ofNullable(altairForkEpoch),
Optional.ofNullable(bellatrixForkEpoch),
Optional.ofNullable(network),
keyManagerApiEnabled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ private String createEth2SlashingProtectionArgs() {
signerConfig.getAltairForkEpoch().get()));
}

if (signerConfig.getBellatrixForkEpoch().isPresent()) {
yamlConfig.append(
String.format(
YAML_NUMERIC_FMT,
"eth2.Xnetwork-bellatrix-fork-epoch",
signerConfig.getBellatrixForkEpoch().get()));
}

if (signerConfig.getNetwork().isPresent()) {
yamlConfig.append(
String.format(YAML_STRING_FMT, "eth2.network", signerConfig.getNetwork().get()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ private Collection<String> createEth2Args() {
params.add(Long.toString(signerConfig.getAltairForkEpoch().get()));
}

if (signerConfig.getBellatrixForkEpoch().isPresent()) {
params.add("--Xnetwork-bellatrix-fork-epoch");
params.add(Long.toString(signerConfig.getBellatrixForkEpoch().get()));
}

if (signerConfig.getNetwork().isPresent()) {
params.add("--network");
params.add(signerConfig.getNetwork().get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package tech.pegasys.web3signer.dsl.utils;

import tech.pegasys.teku.api.schema.BeaconBlockHeader;
import tech.pegasys.teku.api.schema.Fork;
import tech.pegasys.teku.api.schema.altair.BeaconBlockAltair;
import tech.pegasys.teku.api.schema.altair.BeaconBlockBodyAltair;
Expand Down Expand Up @@ -40,17 +41,7 @@ public class Eth2BlockSigningRequestUtil {
private final Bytes signingRoot;

public Eth2BlockSigningRequestUtil(final SpecMilestone specMilestone) {
final Spec spec;
switch (specMilestone) {
case ALTAIR:
spec = TestSpecFactory.createMinimalAltair();
break;
case PHASE0:
spec = TestSpecFactory.createMinimalPhase0();
break;
default:
throw new IllegalStateException("Spec Milestone not yet supported: " + specMilestone);
}
final Spec spec = TestSpecFactory.createMinimal(specMilestone);
this.specMilestone = specMilestone;
dataStructureUtil = new DataStructureUtil(spec);
signingRootUtil = new SigningRootUtil(spec);
Expand All @@ -64,8 +55,19 @@ public Eth2BlockSigningRequestUtil(final SpecMilestone specMilestone) {
}

public Eth2SigningRequestBody createBlockV2Request() {
final BlockRequest blockRequest = new BlockRequest(specMilestone, getBeaconBlock());
switch (specMilestone) {
case PHASE0:
case ALTAIR:
return createBlockV2Request(new BlockRequest(specMilestone, getBeaconBlock()));
case BELLATRIX:
return createBlockV2Request(new BlockRequest(specMilestone, getBeaconBlockHeader()));
default:
throw new IllegalStateException(
"Spec not yet implemented for BLOCKV2 Signing AT: " + specMilestone);
}
}

public Eth2SigningRequestBody createBlockV2Request(final BlockRequest blockRequest) {
return new Eth2SigningRequestBody(
ArtifactType.BLOCK_V2,
signingRoot,
Expand Down Expand Up @@ -106,19 +108,29 @@ public Eth2SigningRequestBody createLegacyBlockRequest() {
null);
}

private BeaconBlockHeader getBeaconBlockHeader() {
return new BeaconBlockHeader(
beaconBlock.getSlot(),
beaconBlock.getProposerIndex(),
beaconBlock.getParentRoot(),
beaconBlock.getStateRoot(),
beaconBlock.getBodyRoot());
}

private tech.pegasys.teku.api.schema.BeaconBlock getBeaconBlock() {
if (specMilestone == SpecMilestone.ALTAIR) {
return new BeaconBlockAltair(
beaconBlock.getSlot(),
beaconBlock.getProposerIndex(),
beaconBlock.getParentRoot(),
beaconBlock.getStateRoot(),
getBeaconBlockBodyAltair(beaconBlock.getBody()));
} else if (specMilestone == SpecMilestone.PHASE0) {
return new BeaconBlockPhase0(beaconBlock);
switch (specMilestone) {
case PHASE0:
return new BeaconBlockPhase0(beaconBlock);
case ALTAIR:
return new BeaconBlockAltair(
beaconBlock.getSlot(),
beaconBlock.getProposerIndex(),
beaconBlock.getParentRoot(),
beaconBlock.getStateRoot(),
getBeaconBlockBodyAltair(beaconBlock.getBody()));
default:
throw new IllegalStateException("BeaconBlock only supported for PHASE0 and ALTAIR in AT");
}

throw new IllegalStateException("Spec milestone not yet supported: " + specMilestone);
}

private BeaconBlockBodyAltair getBeaconBlockBodyAltair(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSecretKey;
import tech.pegasys.teku.bls.BLSSignature;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.web3signer.core.service.http.ArtifactType;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SigningRequestBody;
import tech.pegasys.web3signer.dsl.HashicorpSigningParams;
Expand Down Expand Up @@ -290,10 +292,10 @@ private void setupMinimalWeb3Signer(ArtifactType artifactType) {
case SYNC_COMMITTEE_MESSAGE:
case SYNC_COMMITTEE_SELECTION_PROOF:
case SYNC_COMMITTEE_CONTRIBUTION_AND_PROOF:
setupEth2SignerMinimal();
setupEth2Signer(Eth2Network.MINIMAL, SpecMilestone.ALTAIR);
break;
default:
setupEth2SignerMinimalWithoutAltairFork();
setupEth2Signer(Eth2Network.MINIMAL, SpecMilestone.PHASE0);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@
package tech.pegasys.web3signer.tests.signing;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;

import tech.pegasys.teku.bls.BLS;
import tech.pegasys.teku.bls.BLSKeyPair;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSecretKey;
import tech.pegasys.teku.bls.BLSSignature;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.BlockRequest;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SigningRequestBody;
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 com.fasterxml.jackson.core.JsonProcessingException;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.apache.tuweni.bytes.Bytes;
Expand All @@ -37,7 +39,7 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

public class Eth2AltairBlockSigningAcceptanceTest extends SigningAcceptanceTestBase {
public class Eth2BlockSigningAcceptanceTest extends SigningAcceptanceTestBase {
private static final String PRIVATE_KEY =
"3ee2224386c82ffea477e2adf28a2929f5c349165a4196158c7f3a2ecca40f35";

Expand All @@ -57,20 +59,11 @@ void setup() {
@ParameterizedTest
@EnumSource(
value = SpecMilestone.class,
names = {"PHASE0", "ALTAIR"})
names = {"PHASE0", "ALTAIR", "BELLATRIX"})
void signAndVerifyBlockV2Signature(final SpecMilestone specMilestone) throws Exception {
final Eth2BlockSigningRequestUtil util = new Eth2BlockSigningRequestUtil(specMilestone);

switch (specMilestone) {
case ALTAIR:
setupEth2SignerMinimal();
break;
case PHASE0:
setupEth2SignerMinimalWithoutAltairFork();
break;
default:
fail("Spec milestone not yet supported" + specMilestone);
}
setupEth2Signer(Eth2Network.MINIMAL, specMilestone);

final Eth2SigningRequestBody request = util.createBlockV2Request();
final Response response =
Expand All @@ -84,7 +77,7 @@ void signAndVerifyBlockV2Signature(final SpecMilestone specMilestone) throws Exc
@Test
void signAndVerifyLegacyBlockSignature() throws Exception {
final Eth2BlockSigningRequestUtil util = new Eth2BlockSigningRequestUtil(SpecMilestone.PHASE0);
setupEth2SignerMinimalWithoutAltairFork();
setupEth2Signer(Eth2Network.MINIMAL, SpecMilestone.PHASE0);

final Eth2SigningRequestBody request = util.createLegacyBlockRequest();
final Response response =
Expand All @@ -94,4 +87,18 @@ void signAndVerifyLegacyBlockSignature() throws Exception {
BLS.sign(keyPair.getSecretKey(), request.getSigningRoot());
assertThat(signature).isEqualTo(expectedSignature.toBytesCompressed());
}

@Test
void emptyBlockRequestReturnsBadRequestStatus() throws JsonProcessingException {
final Eth2BlockSigningRequestUtil util =
new Eth2BlockSigningRequestUtil(SpecMilestone.BELLATRIX);
setupEth2Signer(Eth2Network.MINIMAL, SpecMilestone.BELLATRIX);

final Eth2SigningRequestBody request =
util.createBlockV2Request(new BlockRequest(SpecMilestone.BELLATRIX));
final Response response =
signer.eth2Sign(keyPair.getPublicKey().toString(), request, ContentType.JSON);

response.then().statusCode(400);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import tech.pegasys.teku.api.schema.BLSPubKey;
import tech.pegasys.teku.infrastructure.bytes.Bytes4;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.web3signer.core.service.http.ArtifactType;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.DepositMessage;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SigningRequestBody;
Expand Down Expand Up @@ -56,7 +58,7 @@ List<DynamicTest> signDepositData() {
metadataFileHelpers.createUnencryptedYamlFileAt(
testDirectory.resolve("2.yaml"), PRIVATE_KEY2, BLS);

setupEth2Signer();
setupEth2Signer(Eth2Network.MAINNET, SpecMilestone.ALTAIR);

final ObjectMapper objectMapper = JsonMapper.builder().build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import tech.pegasys.teku.bls.BLSKeyPair;
import tech.pegasys.teku.bls.BLSPublicKey;
import tech.pegasys.teku.bls.BLSSecretKey;
import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SigningRequestBody;
import tech.pegasys.web3signer.dsl.signer.Signer;
import tech.pegasys.web3signer.dsl.utils.Eth2RequestUtils;
Expand Down Expand Up @@ -59,7 +61,7 @@ public void receiveA404IfRequestedKeyDoesNotExist(final KeyType keyType)
if (keyType == KeyType.BLS) {
setupEth1Signer();
} else {
setupEth2Signer();
setupEth2Signer(Eth2Network.MAINNET, SpecMilestone.ALTAIR);
}
final String body = createBody(keyType);
given()
Expand All @@ -82,7 +84,7 @@ public void receiveA400IfDataIsNotValid(final String data) {
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml");
METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS);

setupEth2Signer();
setupEth2Signer(Eth2Network.MAINNET, SpecMilestone.ALTAIR);

// without client-side openapi validator
given()
Expand All @@ -103,7 +105,7 @@ public void receiveA400IfDataIsMissingFromJsonBody() {
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml");
METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS);

setupEth2Signer();
setupEth2Signer(Eth2Network.MAINNET, SpecMilestone.ALTAIR);

// without OpenAPI validation filter
given()
Expand All @@ -124,7 +126,7 @@ public void receiveA400IfJsonBodyIsMalformed() {
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml");
METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS);

setupEth2Signer();
setupEth2Signer(Eth2Network.MAINNET, SpecMilestone.ALTAIR);

// without OpenAPI validation filter
given()
Expand All @@ -145,7 +147,7 @@ public void unusedFieldsInRequestDoesNotAffectSigning() throws JsonProcessingExc
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml");
METADATA_FILE_HELPERS.createUnencryptedYamlFileAt(keyConfigFile, PRIVATE_KEY, KeyType.BLS);

setupEth2SignerMinimalWithoutAltairFork();
setupEth2Signer(Eth2Network.MINIMAL, SpecMilestone.PHASE0);

final Eth2SigningRequestBody blockRequest = Eth2RequestUtils.createBlockRequest();
final JsonObject jsonObject =
Expand Down
Loading

0 comments on commit 8fe4798

Please sign in to comment.