-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebccf38
commit 5a8a343
Showing
14 changed files
with
352 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
.../main/java/tech/pegasys/web3signer/core/routes/eth2/CommitBoostRequestSignatureRoute.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright 2024 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. | ||
*/ | ||
package tech.pegasys.web3signer.core.routes.eth2; | ||
|
||
import tech.pegasys.teku.spec.Spec; | ||
import tech.pegasys.web3signer.core.Context; | ||
import tech.pegasys.web3signer.core.routes.Web3SignerRoute; | ||
import tech.pegasys.web3signer.core.service.http.handlers.commitboost.CommitBoostRequestSignatureHandler; | ||
import tech.pegasys.web3signer.signing.ArtifactSignerProvider; | ||
import tech.pegasys.web3signer.signing.config.CommitBoostParameters; | ||
import tech.pegasys.web3signer.signing.config.DefaultArtifactSignerProvider; | ||
|
||
import io.vertx.core.http.HttpMethod; | ||
import io.vertx.core.json.JsonObject; | ||
|
||
public class CommitBoostRequestSignatureRoute implements Web3SignerRoute { | ||
private static final String PATH = "/signer/v1/request_signature"; | ||
private final Context context; | ||
private final CommitBoostParameters commitBoostParameters; | ||
private final Spec eth2Spec; | ||
private final ArtifactSignerProvider artifactSignerProvider; | ||
|
||
public CommitBoostRequestSignatureRoute( | ||
final Context context, | ||
final CommitBoostParameters commitBoostParameters, | ||
final Spec eth2Spec) { | ||
this.context = context; | ||
this.commitBoostParameters = commitBoostParameters; | ||
this.eth2Spec = eth2Spec; | ||
|
||
// there should be only one DefaultArtifactSignerProvider in eth2 mode | ||
artifactSignerProvider = | ||
context.getArtifactSignerProviders().stream() | ||
.filter(p -> p instanceof DefaultArtifactSignerProvider) | ||
.findFirst() | ||
.orElseThrow(); | ||
} | ||
|
||
@Override | ||
public void register() { | ||
context | ||
.getRouter() | ||
.route(HttpMethod.POST, PATH) | ||
.blockingHandler( | ||
new CommitBoostRequestSignatureHandler( | ||
artifactSignerProvider, commitBoostParameters, eth2Spec), | ||
false) | ||
.failureHandler(context.getErrorHandler()) | ||
.failureHandler( | ||
ctx -> { | ||
final int statusCode = ctx.statusCode(); | ||
if (statusCode == 400) { | ||
ctx.response() | ||
.setStatusCode(statusCode) | ||
.end( | ||
new JsonObject() | ||
.put("code", statusCode) | ||
.put("message", "Bad Request") | ||
.encode()); | ||
} else if (statusCode == 404) { | ||
ctx.response() | ||
.setStatusCode(statusCode) | ||
.end( | ||
new JsonObject() | ||
.put("code", statusCode) | ||
.put("message", "Identifier not found.") | ||
.encode()); | ||
} else if (statusCode == 500) { | ||
ctx.response() | ||
.setStatusCode(statusCode) | ||
.end( | ||
new JsonObject() | ||
.put("code", statusCode) | ||
.put("message", "Internal Server Error") | ||
.encode()); | ||
} else { | ||
ctx.next(); // go to global failure handler | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
...web3signer/core/service/http/handlers/commitboost/CommitBoostRequestSignatureHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright 2024 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. | ||
*/ | ||
package tech.pegasys.web3signer.core.service.http.handlers.commitboost; | ||
|
||
import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE; | ||
import static tech.pegasys.web3signer.core.service.http.handlers.ContentTypes.JSON_UTF_8; | ||
import static tech.pegasys.web3signer.signing.util.IdentifierUtils.normaliseIdentifier; | ||
|
||
import tech.pegasys.teku.spec.Spec; | ||
import tech.pegasys.web3signer.core.service.http.SigningObjectMapperFactory; | ||
import tech.pegasys.web3signer.core.service.http.handlers.commitboost.json.RequestSignatureBody; | ||
import tech.pegasys.web3signer.signing.ArtifactSignerProvider; | ||
import tech.pegasys.web3signer.signing.config.CommitBoostParameters; | ||
|
||
import java.util.Optional; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import io.vertx.core.Handler; | ||
import io.vertx.ext.web.RoutingContext; | ||
import org.apache.tuweni.bytes.Bytes32; | ||
|
||
public class CommitBoostRequestSignatureHandler implements Handler<RoutingContext> { | ||
private static final ObjectMapper JSON_MAPPER = SigningObjectMapperFactory.createObjectMapper(); | ||
private static final int NOT_FOUND = 404; | ||
private static final int BAD_REQUEST = 400; | ||
private static final int INTERNAL_ERROR = 500; | ||
|
||
private final CommitBoostSigner commitBoostSigner; | ||
private final SigningRootGenerator signingRootGenerator; | ||
|
||
public CommitBoostRequestSignatureHandler( | ||
final ArtifactSignerProvider artifactSignerProvider, | ||
final CommitBoostParameters commitBoostParameters, | ||
final Spec eth2Spec) { | ||
commitBoostSigner = new CommitBoostSigner(artifactSignerProvider); | ||
this.signingRootGenerator = | ||
new SigningRootGenerator(eth2Spec, commitBoostParameters.getGenesisValidatorsRoot()); | ||
} | ||
|
||
@Override | ||
public void handle(final RoutingContext context) { | ||
final String body = context.body().asString(); | ||
|
||
// read and validate incoming json body | ||
final RequestSignatureBody requestSignatureBody; | ||
try { | ||
requestSignatureBody = JSON_MAPPER.readValue(body, RequestSignatureBody.class); | ||
} catch (final JsonProcessingException | IllegalArgumentException e) { | ||
context.fail(BAD_REQUEST); | ||
return; | ||
} | ||
try { | ||
// Check for pubkey based on signing type, if not exist, fail with 404 | ||
final String identifier = normaliseIdentifier(requestSignatureBody.publicKey()); | ||
if (!commitBoostSigner.isSignerAvailable(identifier, requestSignatureBody.type())) { | ||
context.fail(NOT_FOUND); | ||
return; | ||
} | ||
|
||
// Calculate Signing root and sign the request | ||
final Bytes32 signingRoot = | ||
signingRootGenerator.computeSigningRoot(requestSignatureBody.objectRoot()); | ||
final Optional<String> optionalSig = | ||
commitBoostSigner.sign(identifier, requestSignatureBody.type(), signingRoot); | ||
if (optionalSig.isEmpty()) { | ||
context.fail(NOT_FOUND); | ||
return; | ||
} | ||
|
||
// Encode and send response | ||
final String jsonEncoded = JSON_MAPPER.writeValueAsString(optionalSig.get()); | ||
context.response().putHeader(CONTENT_TYPE, JSON_UTF_8).end(jsonEncoded); | ||
} catch (final Exception e) { | ||
context.fail(INTERNAL_ERROR, e); | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
...ava/tech/pegasys/web3signer/core/service/http/handlers/commitboost/CommitBoostSigner.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2024 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. | ||
*/ | ||
package tech.pegasys.web3signer.core.service.http.handlers.commitboost; | ||
|
||
import tech.pegasys.web3signer.core.service.http.handlers.commitboost.json.SignRequestType; | ||
import tech.pegasys.web3signer.signing.ArtifactSignature; | ||
import tech.pegasys.web3signer.signing.ArtifactSigner; | ||
import tech.pegasys.web3signer.signing.ArtifactSignerProvider; | ||
import tech.pegasys.web3signer.signing.BlsArtifactSignature; | ||
import tech.pegasys.web3signer.signing.KeyType; | ||
import tech.pegasys.web3signer.signing.SecpArtifactSignature; | ||
|
||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import org.apache.tuweni.bytes.Bytes32; | ||
|
||
public class CommitBoostSigner { | ||
private final ArtifactSignerProvider artifactSignerProvider; | ||
|
||
public CommitBoostSigner(final ArtifactSignerProvider artifactSignerProvider) { | ||
this.artifactSignerProvider = artifactSignerProvider; | ||
} | ||
|
||
public boolean isSignerAvailable(final String identifier, final SignRequestType type) { | ||
return switch (type) { | ||
case CONSENSUS -> artifactSignerProvider.availableIdentifiers().contains(identifier); | ||
case PROXY_BLS -> { | ||
final Map<KeyType, Set<String>> proxyIdentifiers = | ||
artifactSignerProvider.getProxyIdentifiers(identifier); | ||
yield proxyIdentifiers.containsKey(KeyType.BLS) | ||
&& proxyIdentifiers.get(KeyType.BLS).contains(identifier); | ||
} | ||
case PROXY_ECDSA -> { | ||
final Map<KeyType, Set<String>> proxyIdentifiers = | ||
artifactSignerProvider.getProxyIdentifiers(identifier); | ||
yield proxyIdentifiers.containsKey(KeyType.SECP256K1) | ||
&& proxyIdentifiers.get(KeyType.SECP256K1).contains(identifier); | ||
} | ||
}; | ||
} | ||
|
||
public Optional<String> sign( | ||
final String identifier, final SignRequestType type, final Bytes32 signingRoot) { | ||
final Optional<ArtifactSigner> optionalArtifactSigner = | ||
type == SignRequestType.CONSENSUS | ||
? artifactSignerProvider.getSigner(identifier) | ||
: artifactSignerProvider.getProxySigner(identifier); | ||
|
||
return optionalArtifactSigner | ||
.map( | ||
signer -> { | ||
final ArtifactSignature artifactSignature = signer.sign(signingRoot); | ||
return switch (artifactSignature.getType()) { | ||
case BLS -> | ||
Optional.of( | ||
((BlsArtifactSignature) artifactSignature).getSignatureData().toString()); | ||
case SECP256K1 -> | ||
Optional.of( | ||
SecpArtifactSignature.toBytes((SecpArtifactSignature) artifactSignature) | ||
.toHexString()); | ||
}; | ||
}) | ||
.orElse(Optional.empty()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
.../pegasys/web3signer/core/service/http/handlers/commitboost/json/RequestSignatureBody.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright 2024 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. | ||
*/ | ||
package tech.pegasys.web3signer.core.service.http.handlers.commitboost.json; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import org.apache.tuweni.bytes.Bytes32; | ||
|
||
public record RequestSignatureBody( | ||
@JsonProperty(value = "type", required = true) SignRequestType type, | ||
@JsonProperty(value = "pubkey", required = true) String publicKey, | ||
@JsonProperty(value = "object_root", required = true) Bytes32 objectRoot) {} |
19 changes: 19 additions & 0 deletions
19
.../tech/pegasys/web3signer/core/service/http/handlers/commitboost/json/SignRequestType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright 2024 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. | ||
*/ | ||
package tech.pegasys.web3signer.core.service.http.handlers.commitboost.json; | ||
|
||
public enum SignRequestType { | ||
CONSENSUS, | ||
PROXY_BLS, | ||
PROXY_ECDSA | ||
} |
Oops, something went wrong.