diff --git a/core/src/main/java/tech/pegasys/web3signer/core/Eth2Runner.java b/core/src/main/java/tech/pegasys/web3signer/core/Eth2Runner.java index dd1a3abdf..a856351b2 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/Eth2Runner.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/Eth2Runner.java @@ -235,13 +235,12 @@ private MappedResults bulkLoadSigners( if (keystoresParameters.isEnabled()) { LOG.info("Bulk loading keys from local keystores ... "); - final BlsKeystoreBulkLoader blsKeystoreBulkLoader = new BlsKeystoreBulkLoader(); final MappedResults keystoreSignersResult = keystoresParameters.hasKeystoresPasswordsPath() - ? blsKeystoreBulkLoader.loadKeystoresUsingPasswordDir( + ? BlsKeystoreBulkLoader.loadKeystoresUsingPasswordDir( keystoresParameters.getKeystoresPath(), keystoresParameters.getKeystoresPasswordsPath()) - : blsKeystoreBulkLoader.loadKeystoresUsingPasswordFile( + : BlsKeystoreBulkLoader.loadKeystoresUsingPasswordFile( keystoresParameters.getKeystoresPath(), keystoresParameters.getKeystoresPasswordFile()); LOG.info( diff --git a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/Eth1SignRoute.java b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/Eth1SignRoute.java index cdd1db7f1..ba4b3d9cd 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/Eth1SignRoute.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/Eth1SignRoute.java @@ -20,7 +20,6 @@ import tech.pegasys.web3signer.core.service.http.handlers.signing.SignerForIdentifier; import tech.pegasys.web3signer.core.service.http.metrics.HttpApiMetrics; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import tech.pegasys.web3signer.signing.config.DefaultArtifactSignerProvider; import java.util.Optional; @@ -33,7 +32,7 @@ public class Eth1SignRoute implements Web3SignerRoute { private final Context context; private final ArtifactSignerProvider signerProvider; - private final SignerForIdentifier secpSigner; + private final SignerForIdentifier secpSigner; public Eth1SignRoute(final Context context) { this.context = context; @@ -46,9 +45,7 @@ public Eth1SignRoute(final Context context) { if (first.isPresent()) { signerProvider = first.get(); - secpSigner = - new SignerForIdentifier<>( - signerProvider, sig -> SecpArtifactSignature.toBytes(sig).toHexString(), SECP256K1); + secpSigner = new SignerForIdentifier(signerProvider); } else { throw new IllegalStateException( "No DefaultArtifactSignerProvider found in Context for eth1 mode"); diff --git a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/JsonRpcRoute.java b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/JsonRpcRoute.java index ffefa21b3..f78a72a2f 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/JsonRpcRoute.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth1/JsonRpcRoute.java @@ -12,8 +12,6 @@ */ package tech.pegasys.web3signer.core.routes.eth1; -import static tech.pegasys.web3signer.signing.KeyType.SECP256K1; - import tech.pegasys.web3signer.core.Context; import tech.pegasys.web3signer.core.Runner; import tech.pegasys.web3signer.core.WebClientOptionsFactory; @@ -38,11 +36,8 @@ import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.SendTransactionHandler; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.transaction.TransactionFactory; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import tech.pegasys.web3signer.signing.config.SecpArtifactSignerProviderAdapter; -import java.util.Optional; - import io.vertx.core.Vertx; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpMethod; @@ -62,18 +57,17 @@ public class JsonRpcRoute implements Web3SignerRoute { public JsonRpcRoute(final Context context, final Eth1Config eth1Config) { this.context = context; - // we need signerProvider which is an instance of SecpArtifactSignerProviderAdapter - final Optional first = + // we need signerProvider which is an instance of SecpArtifactSignerProviderAdapter which uses + // eth1 address as identifier + final ArtifactSignerProvider signerProvider = context.getArtifactSignerProviders().stream() .filter(provider -> provider instanceof SecpArtifactSignerProviderAdapter) - .findFirst(); - final ArtifactSignerProvider signerProvider; - if (first.isPresent()) { - signerProvider = first.get(); - } else { - throw new IllegalStateException( - "No SecpArtifactSignerProviderAdapter found in Context for eth1 mode"); - } + .findFirst() + .orElseThrow( + () -> + new IllegalStateException( + "No SecpArtifactSignerProviderAdapter found in Context for eth1 mode")); + // use same instance of downstreamHttpClient and path calculator for all requests final HttpClient downstreamHttpClient = createDownstreamHttpClient(eth1Config, context.getVertx()); @@ -126,11 +120,8 @@ private static RequestMapper createRequestMapper( final long chainId) { final PassThroughHandler defaultHandler = new PassThroughHandler(transmitterFactory, JSON_DECODER); - final SignerForIdentifier secpSigner = - new SignerForIdentifier<>( - signerProviderMappedToEth1Address, - sig -> SecpArtifactSignature.toBytes(sig).toHexString(), - SECP256K1); + final SignerForIdentifier secpSigner = + new SignerForIdentifier(signerProviderMappedToEth1Address); final TransactionFactory transactionFactory = new TransactionFactory(chainId, JSON_DECODER, transmitterFactory); final SendTransactionHandler sendTransactionHandler = diff --git a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignExtensionRoute.java b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignExtensionRoute.java index c5caac682..a338b95d8 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignExtensionRoute.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignExtensionRoute.java @@ -12,14 +12,11 @@ */ package tech.pegasys.web3signer.core.routes.eth2; -import static tech.pegasys.web3signer.signing.KeyType.BLS; - import tech.pegasys.web3signer.core.Context; import tech.pegasys.web3signer.core.routes.Web3SignerRoute; import tech.pegasys.web3signer.core.service.http.handlers.signing.SignerForIdentifier; import tech.pegasys.web3signer.core.service.http.handlers.signing.SigningExtensionHandler; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.BlsArtifactSignature; import io.vertx.core.http.HttpMethod; import io.vertx.core.json.JsonObject; @@ -28,7 +25,7 @@ public class Eth2SignExtensionRoute implements Web3SignerRoute { public static final String SIGN_EXT_PATH = "/api/v1/eth2/ext/sign/:identifier"; private final Context context; - private final SignerForIdentifier blsSigner; + private final SignerForIdentifier blsSigner; public Eth2SignExtensionRoute(final Context context) { this.context = context; @@ -36,11 +33,14 @@ public Eth2SignExtensionRoute(final Context context) { // there should be only one ArtifactSignerProvider in eth2 mode at the moment which is of BLS // types. final ArtifactSignerProvider artifactSignerProvider = - context.getArtifactSignerProviders().stream().findFirst().orElseThrow(); + context.getArtifactSignerProviders().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException( + "No ArtifactSignerProvider found in Context for eth2 mode")); - blsSigner = - new SignerForIdentifier<>( - artifactSignerProvider, sig -> sig.getSignatureData().toString(), BLS); + blsSigner = new SignerForIdentifier(artifactSignerProvider); } @Override diff --git a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignRoute.java b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignRoute.java index c54e42da6..27aaa2c38 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignRoute.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/routes/eth2/Eth2SignRoute.java @@ -23,7 +23,6 @@ import tech.pegasys.web3signer.core.service.http.handlers.signing.eth2.Eth2SignForIdentifierHandler; import tech.pegasys.web3signer.core.service.http.metrics.HttpApiMetrics; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.BlsArtifactSignature; import tech.pegasys.web3signer.slashingprotection.SlashingProtection; import tech.pegasys.web3signer.slashingprotection.SlashingProtectionContext; @@ -36,7 +35,7 @@ public class Eth2SignRoute implements Web3SignerRoute { private static final String SIGN_PATH = "/api/v1/eth2/sign/:identifier"; private final Context context; - private final SignerForIdentifier blsSigner; + private final SignerForIdentifier blsSigner; private final ObjectMapper objectMapper = SigningObjectMapperFactory.createObjectMapper(); private final Spec eth2Spec; private final Optional slashingProtection; @@ -52,11 +51,14 @@ public Eth2SignRoute( // there should be only one ArtifactSignerProvider in eth2 mode at the moment which is of BLS // types. final ArtifactSignerProvider artifactSignerProvider = - context.getArtifactSignerProviders().stream().findFirst().orElseThrow(); + context.getArtifactSignerProviders().stream() + .findFirst() + .orElseThrow( + () -> + new IllegalStateException( + "No ArtifactSignerProvider found in Context for eth2 mode")); - blsSigner = - new SignerForIdentifier<>( - artifactSignerProvider, sig -> sig.getSignatureData().toString(), BLS); + blsSigner = new SignerForIdentifier(artifactSignerProvider); } @Override diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/Eth1SignForIdentifierHandler.java b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/Eth1SignForIdentifierHandler.java index 2c459976c..becfac852 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/Eth1SignForIdentifierHandler.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/Eth1SignForIdentifierHandler.java @@ -14,7 +14,6 @@ import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE; import static tech.pegasys.web3signer.core.service.http.handlers.ContentTypes.TEXT_PLAIN_UTF_8; -import static tech.pegasys.web3signer.core.service.http.handlers.signing.SignerForIdentifier.toBytes; import static tech.pegasys.web3signer.signing.util.IdentifierUtils.normaliseIdentifier; import tech.pegasys.web3signer.core.service.http.metrics.HttpApiMetrics; @@ -23,6 +22,7 @@ import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RequestBody; import io.vertx.ext.web.RoutingContext; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.tuweni.bytes.Bytes; @@ -31,11 +31,11 @@ public class Eth1SignForIdentifierHandler implements Handler { private static final Logger LOG = LogManager.getLogger(); - private final SignerForIdentifier signerForIdentifier; + private final SignerForIdentifier signerForIdentifier; private final HttpApiMetrics metrics; public Eth1SignForIdentifierHandler( - final SignerForIdentifier signerForIdentifier, final HttpApiMetrics metrics) { + final SignerForIdentifier signerForIdentifier, final HttpApiMetrics metrics) { this.signerForIdentifier = signerForIdentifier; this.metrics = metrics; } @@ -47,7 +47,7 @@ public void handle(final RoutingContext routingContext) { final Bytes data; try { data = getDataToSign(routingContext.body()); - } catch (final IllegalArgumentException e) { + } catch (final RuntimeException e) { metrics.getMalformedRequestCounter().inc(); LOG.debug("Invalid signing request", e); routingContext.fail(400); @@ -72,6 +72,14 @@ private void respondWithSignature(final RoutingContext routingContext, final Str private Bytes getDataToSign(final RequestBody requestBody) { final JsonObject jsonObject = requestBody.asJsonObject(); - return toBytes(jsonObject.getString("data")); + + if (!jsonObject.containsKey("data")) { + throw new IllegalArgumentException("Request must contain a 'data' field"); + } + if (StringUtils.isBlank(jsonObject.getString("data"))) { + throw new IllegalArgumentException("Data field must not be empty"); + } + + return Bytes.fromHexString(jsonObject.getString("data")); } } diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignatureFormatter.java b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignatureFormatter.java deleted file mode 100644 index 103c531c5..000000000 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignatureFormatter.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020 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.signing; - -import tech.pegasys.web3signer.signing.ArtifactSignature; - -@FunctionalInterface -public interface SignatureFormatter { - - String format(T signature); -} diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignerForIdentifier.java b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignerForIdentifier.java index 7148fb6fd..d2b717451 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignerForIdentifier.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SignerForIdentifier.java @@ -14,28 +14,20 @@ import tech.pegasys.web3signer.signing.ArtifactSignature; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.KeyType; import java.util.Optional; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.apache.tuweni.bytes.Bytes; -public class SignerForIdentifier { - private static final Logger LOG = LogManager.getLogger(); +/** + * This class wraps the {@link ArtifactSignerProvider} and provides a way to check if a signer is + * available for a given identifier and to sign a message. + */ +public class SignerForIdentifier { private final ArtifactSignerProvider signerProvider; - private final SignatureFormatter signatureFormatter; - private final KeyType type; - public SignerForIdentifier( - final ArtifactSignerProvider signerProvider, - final SignatureFormatter signatureFormatter, - final KeyType type) { + public SignerForIdentifier(final ArtifactSignerProvider signerProvider) { this.signerProvider = signerProvider; - this.signatureFormatter = signatureFormatter; - this.type = type; } /** @@ -48,43 +40,19 @@ public SignerForIdentifier( * @throws IllegalArgumentException if data is invalid i.e. not a valid hex string, null or empty. */ public Optional sign(final String identifier, final Bytes data) { - return signerProvider.getSigner(identifier).map(signer -> formatSignature(signer.sign(data))); - } - - @SuppressWarnings("unchecked") - public Optional signAndGetArtifactSignature(final String identifier, final Bytes data) { - return signerProvider.getSigner(identifier).map(signer -> (T) signer.sign(data)); + return signerProvider.getSigner(identifier).map(signer -> signer.sign(data).asHex()); } /** - * Converts hex string to bytes + * Sign data for given identifier and return ArtifactSignature. Useful for SECP signing. * - * @param data hex string - * @return Bytes - * @throws IllegalArgumentException if data is invalid i.e. not a valid hex string, null or empty + * @param identifier The identifier for which to sign data. + * @param data Bytes which is signed + * @return Optional ArtifactSignature. Empty if no signer available for given identifier */ - public static Bytes toBytes(final String data) { - final Bytes dataToSign; - try { - if (StringUtils.isBlank(data)) { - throw new IllegalArgumentException("Blank data"); - } - dataToSign = Bytes.fromHexString(data); - } catch (final IllegalArgumentException e) { - LOG.debug("Invalid hex string {}", data, e); - throw e; - } - return dataToSign; - } - - @SuppressWarnings("unchecked") - private String formatSignature(final ArtifactSignature signature) { - if (signature.getType() == type) { - final T artifactSignature = (T) signature; - return signatureFormatter.format(artifactSignature); - } else { - throw new IllegalStateException("Invalid signature type"); - } + public Optional signAndGetArtifactSignature( + final String identifier, final Bytes data) { + return signerProvider.getSigner(identifier).map(signer -> signer.sign(data)); } /** diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SigningExtensionHandler.java b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SigningExtensionHandler.java index be9100a2a..596d15e5d 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SigningExtensionHandler.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/SigningExtensionHandler.java @@ -36,9 +36,9 @@ public class SigningExtensionHandler implements Handler { .copy() .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - private final SignerForIdentifier signerForIdentifier; + private final SignerForIdentifier signerForIdentifier; - public SigningExtensionHandler(final SignerForIdentifier signerForIdentifier) { + public SigningExtensionHandler(final SignerForIdentifier signerForIdentifier) { this.signerForIdentifier = signerForIdentifier; } diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/eth2/Eth2SignForIdentifierHandler.java b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/eth2/Eth2SignForIdentifierHandler.java index ffca43dd7..da682da19 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/eth2/Eth2SignForIdentifierHandler.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/http/handlers/signing/eth2/Eth2SignForIdentifierHandler.java @@ -56,7 +56,7 @@ public class Eth2SignForIdentifierHandler implements Handler { private static final Logger LOG = LogManager.getLogger(); - private final SignerForIdentifier signerForIdentifier; + private final SignerForIdentifier signerForIdentifier; private final HttpApiMetrics httpMetrics; private final SlashingProtectionMetrics slashingMetrics; private final Optional slashingProtection; @@ -69,7 +69,7 @@ public class Eth2SignForIdentifierHandler implements Handler { public static final int SLASHING_PROTECTION_ENFORCED = 412; public Eth2SignForIdentifierHandler( - final SignerForIdentifier signerForIdentifier, + final SignerForIdentifier signerForIdentifier, final HttpApiMetrics httpMetrics, final SlashingProtectionMetrics slashingMetrics, final Optional slashingProtection, diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignResultProvider.java b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignResultProvider.java index 80701b0f0..f14b26e5b 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignResultProvider.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignResultProvider.java @@ -21,7 +21,6 @@ import tech.pegasys.web3signer.core.service.jsonrpc.JsonRpcRequest; import tech.pegasys.web3signer.core.service.jsonrpc.exceptions.JsonRpcException; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.ResultProvider; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import java.util.List; @@ -33,10 +32,9 @@ public class EthSignResultProvider implements ResultProvider { private static final Logger LOG = LogManager.getLogger(); - private final SignerForIdentifier transactionSignerProvider; + private final SignerForIdentifier transactionSignerProvider; - public EthSignResultProvider( - final SignerForIdentifier transactionSignerProvider) { + public EthSignResultProvider(final SignerForIdentifier transactionSignerProvider) { this.transactionSignerProvider = transactionSignerProvider; } diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTransactionResultProvider.java b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTransactionResultProvider.java index 2b4b0f700..8043644fc 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTransactionResultProvider.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTransactionResultProvider.java @@ -25,7 +25,6 @@ import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.transaction.EthTransaction; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.transaction.Transaction; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.TransactionSerializer; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import java.util.List; @@ -40,12 +39,10 @@ public class EthSignTransactionResultProvider implements ResultProvider private final long chainId; private final JsonDecoder decoder; - private final SignerForIdentifier secpSigner; + private final SignerForIdentifier secpSigner; public EthSignTransactionResultProvider( - final long chainId, - final SignerForIdentifier secpSigner, - final JsonDecoder decoder) { + final long chainId, final SignerForIdentifier secpSigner, final JsonDecoder decoder) { this.chainId = chainId; this.decoder = decoder; this.secpSigner = secpSigner; diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTypedDataResultProvider.java b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTypedDataResultProvider.java index e3f6be396..a7e1d2cf4 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTypedDataResultProvider.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/internalresponse/EthSignTypedDataResultProvider.java @@ -20,7 +20,6 @@ import tech.pegasys.web3signer.core.service.jsonrpc.JsonRpcRequest; import tech.pegasys.web3signer.core.service.jsonrpc.exceptions.JsonRpcException; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.ResultProvider; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import java.io.IOException; import java.util.List; @@ -34,10 +33,9 @@ public class EthSignTypedDataResultProvider implements ResultProvider { private static final Logger LOG = LogManager.getLogger(); - private final SignerForIdentifier transactionSignerProvider; + private final SignerForIdentifier transactionSignerProvider; - public EthSignTypedDataResultProvider( - final SignerForIdentifier transactionSignerProvider) { + public EthSignTypedDataResultProvider(final SignerForIdentifier transactionSignerProvider) { this.transactionSignerProvider = transactionSignerProvider; } diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/sendtransaction/SendTransactionHandler.java b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/sendtransaction/SendTransactionHandler.java index a090f67a0..2aedfda5b 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/sendtransaction/SendTransactionHandler.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/sendtransaction/SendTransactionHandler.java @@ -26,7 +26,6 @@ import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.transaction.Transaction; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.sendtransaction.transaction.TransactionFactory; import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.TransactionSerializer; -import tech.pegasys.web3signer.signing.SecpArtifactSignature; import io.vertx.core.json.DecodeException; import io.vertx.ext.web.RoutingContext; @@ -41,14 +40,14 @@ public class SendTransactionHandler implements JsonRpcRequestHandler { private final TransactionFactory transactionFactory; private final VertxRequestTransmitterFactory vertxTransmitterFactory; - private final SignerForIdentifier secpSigner; + private final SignerForIdentifier secpSigner; private static final int MAX_NONCE_RETRIES = 10; public SendTransactionHandler( final long chainId, final TransactionFactory transactionFactory, final VertxRequestTransmitterFactory vertxTransmitterFactory, - final SignerForIdentifier secpSigner) { + final SignerForIdentifier secpSigner) { this.chainId = chainId; this.transactionFactory = transactionFactory; this.vertxTransmitterFactory = vertxTransmitterFactory; @@ -89,7 +88,7 @@ public void handle(final RoutingContext context, final JsonRpcRequest request) { private void sendTransaction( final Transaction transaction, final RoutingContext routingContext, - final SignerForIdentifier secpSigner, + final SignerForIdentifier secpSigner, final JsonRpcRequest request) { final TransactionSerializer transactionSerializer = diff --git a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/signing/TransactionSerializer.java b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/signing/TransactionSerializer.java index 233fad7f9..186a17b45 100644 --- a/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/signing/TransactionSerializer.java +++ b/core/src/main/java/tech/pegasys/web3signer/core/service/jsonrpc/handlers/signing/TransactionSerializer.java @@ -32,11 +32,10 @@ public class TransactionSerializer { - protected final SignerForIdentifier secpSigner; + protected final SignerForIdentifier secpSigner; protected final long chainId; - public TransactionSerializer( - final SignerForIdentifier secpSigner, final long chainId) { + public TransactionSerializer(final SignerForIdentifier secpSigner, final long chainId) { this.secpSigner = secpSigner; this.chainId = chainId; } @@ -79,9 +78,11 @@ private static byte[] prependEip1559TransactionType(byte[] bytesToSign) { private SignatureData sign(final String eth1Address, final byte[] bytesToSign) { final SecpArtifactSignature artifactSignature = - secpSigner - .signAndGetArtifactSignature(normaliseIdentifier(eth1Address), Bytes.of(bytesToSign)) - .orElseThrow(() -> new JsonRpcException(SIGNING_FROM_IS_NOT_AN_UNLOCKED_ACCOUNT)); + (SecpArtifactSignature) + secpSigner + .signAndGetArtifactSignature( + normaliseIdentifier(eth1Address), Bytes.of(bytesToSign)) + .orElseThrow(() -> new JsonRpcException(SIGNING_FROM_IS_NOT_AN_UNLOCKED_ACCOUNT)); final Signature signature = artifactSignature.getSignatureData(); diff --git a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignResultProviderTest.java b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignResultProviderTest.java index 78dbe5bcc..77ae13f18 100644 --- a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignResultProviderTest.java +++ b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignResultProviderTest.java @@ -55,7 +55,7 @@ @ExtendWith(MockitoExtension.class) public class EthSignResultProviderTest { - @Mock SignerForIdentifier transactionSignerProvider; + @Mock SignerForIdentifier transactionSignerProvider; @ParameterizedTest @ArgumentsSource(InvalidParamsProvider.class) @@ -97,7 +97,7 @@ public void signatureHasTheExpectedFormat() { final SecpArtifactSignature secpArtifactSignature = new SecpArtifactSignature(new Signature(v, r, s)); - doReturn(Optional.of(SecpArtifactSignature.toBytes(secpArtifactSignature).toHexString())) + doReturn(Optional.of(secpArtifactSignature.asHex())) .when(transactionSignerProvider) .sign(any(), any(Bytes.class)); @@ -138,13 +138,12 @@ public void returnsExpectedSignature(final String message) { Bytes data = answer.getArgument(1, Bytes.class); final Sign.SignatureData signature = Sign.signMessage(data.toArrayUnsafe(), keyPair); return Optional.of( - SecpArtifactSignature.toBytes( - new SecpArtifactSignature( - new Signature( - new BigInteger(signature.getV()), - new BigInteger(1, signature.getR()), - new BigInteger(1, signature.getS())))) - .toHexString()); + new SecpArtifactSignature( + new Signature( + new BigInteger(signature.getV()), + new BigInteger(1, signature.getR()), + new BigInteger(1, signature.getS()))) + .asHex()); }) .when(transactionSignerProvider) .sign(anyString(), any(Bytes.class)); diff --git a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTransactionResultProviderTest.java b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTransactionResultProviderTest.java index e0aab9d00..39820959d 100644 --- a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTransactionResultProviderTest.java +++ b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTransactionResultProviderTest.java @@ -61,7 +61,7 @@ public class EthSignTransactionResultProviderTest { private static JsonDecoder jsonDecoder; private static long chainId; - @Mock SignerForIdentifier mockSignerForIdentifier; + @Mock SignerForIdentifier mockSignerForIdentifier; @BeforeAll static void beforeAll() { diff --git a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTypedDataResultProviderTest.java b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTypedDataResultProviderTest.java index a73a90139..65fe11e1a 100644 --- a/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTypedDataResultProviderTest.java +++ b/core/src/test/java/tech/pegasys/web3signer/core/service/jsonrpc/EthSignTypedDataResultProviderTest.java @@ -71,7 +71,7 @@ public class EthSignTypedDataResultProviderTest { private static final ECKeyPair KEY_PAIR = new ECKeyPair(PRIVATE_KEY, PUBLIC_KEY); - @Mock SignerForIdentifier transactionSignerProvider; + @Mock SignerForIdentifier transactionSignerProvider; @ParameterizedTest @ArgumentsSource(InvalidParamsProvider.class) @@ -147,12 +147,11 @@ public Stream provideArguments(final ExtensionContext conte } private String hexFromSignatureData(Sign.SignatureData signature) { - return SecpArtifactSignature.toBytes( - new SecpArtifactSignature( - new Signature( - new BigInteger(signature.getV()), - new BigInteger(1, signature.getR()), - new BigInteger(1, signature.getS())))) - .toHexString(); + return new SecpArtifactSignature( + new Signature( + new BigInteger(signature.getV()), + new BigInteger(1, signature.getR()), + new BigInteger(1, signature.getS()))) + .asHex(); } } diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignature.java b/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignature.java index 00232fef0..2b9b5afd4 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignature.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignature.java @@ -14,5 +14,17 @@ public interface ArtifactSignature { + /** + * Returns the type of key used to sign the artifact + * + * @return the type of key used to sign the artifact + */ KeyType getType(); + + /** + * Returns the signature data in hex format + * + * @return the signature data in hex format + */ + String asHex(); } diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignerProvider.java b/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignerProvider.java index 985100271..050bddcd7 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignerProvider.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/ArtifactSignerProvider.java @@ -13,7 +13,6 @@ package tech.pegasys.web3signer.signing; import java.io.Closeable; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -44,12 +43,14 @@ public interface ArtifactSignerProvider extends Closeable { Set availableIdentifiers(); /** - * Get the proxy identifiers for the given identifier. Used for commit boost API. + * Get the proxy public keys for the given consensus public key. Used for commit boost API. * - * @param identifier the identifier of the signer + * @param consensusPubKey the identifier of the consensus signer * @return Map of Key Type (BLS, SECP256K1) and corresponding proxy identifiers */ - Map> getProxyIdentifiers(final String identifier); + default Map> getProxyIdentifiers(final String consensusPubKey) { + throw new UnsupportedOperationException("Proxy signers are not supported by this provider"); + } /** * Add a new signer to the signer provider. diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/BlsArtifactSignature.java b/signing/src/main/java/tech/pegasys/web3signer/signing/BlsArtifactSignature.java index 00ce131ce..1aec75556 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/BlsArtifactSignature.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/BlsArtifactSignature.java @@ -29,4 +29,9 @@ public KeyType getType() { public BLSSignature getSignatureData() { return blsSignature; } + + @Override + public String asHex() { + return blsSignature.toString(); + } } diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/SecpArtifactSignature.java b/signing/src/main/java/tech/pegasys/web3signer/signing/SecpArtifactSignature.java index 236288642..667291917 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/SecpArtifactSignature.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/SecpArtifactSignature.java @@ -35,6 +35,15 @@ public Signature getSignatureData() { return signature; } + @Override + public String asHex() { + return Bytes.concatenate( + Bytes32.leftPad(Bytes.wrap(ByteUtils.bigIntegerToBytes(signature.getR()))), + Bytes32.leftPad(Bytes.wrap(ByteUtils.bigIntegerToBytes(signature.getS()))), + Bytes.wrap(ByteUtils.bigIntegerToBytes(signature.getV()))) + .toHexString(); + } + public static SecpArtifactSignature fromBytes(final Bytes signature) { final Bytes r = signature.slice(0, 32); final Bytes s = signature.slice(32, 32); @@ -45,12 +54,4 @@ public static SecpArtifactSignature fromBytes(final Bytes signature) { Numeric.toBigInt(r.toArrayUnsafe()), Numeric.toBigInt(s.toArrayUnsafe()))); } - - public static Bytes toBytes(final SecpArtifactSignature signature) { - final Signature signatureData = signature.getSignatureData(); - return Bytes.concatenate( - Bytes32.leftPad(Bytes.wrap(ByteUtils.bigIntegerToBytes(signatureData.getR()))), - Bytes32.leftPad(Bytes.wrap(ByteUtils.bigIntegerToBytes(signatureData.getS()))), - Bytes.wrap(ByteUtils.bigIntegerToBytes(signatureData.getV()))); - } } diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/bulkloading/BlsKeystoreBulkLoader.java b/signing/src/main/java/tech/pegasys/web3signer/signing/bulkloading/BlsKeystoreBulkLoader.java index 93c66e2f8..53e3267ef 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/bulkloading/BlsKeystoreBulkLoader.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/bulkloading/BlsKeystoreBulkLoader.java @@ -39,7 +39,7 @@ public class BlsKeystoreBulkLoader { private static final Logger LOG = LogManager.getLogger(); - public MappedResults loadKeystoresUsingPasswordDir( + public static MappedResults loadKeystoresUsingPasswordDir( final Path keystoresDirectory, final Path passwordsDirectory) { final List keystoreFiles; try { @@ -59,7 +59,7 @@ public MappedResults loadKeystoresUsingPasswordDir( .reduce(MappedResults.newSetInstance(), MappedResults::merge); } - public MappedResults loadKeystoresUsingPasswordFile( + public static MappedResults loadKeystoresUsingPasswordFile( final Path keystoresDirectory, final Path passwordFile) { final List keystoreFiles; try { @@ -82,7 +82,7 @@ public MappedResults loadKeystoresUsingPasswordFile( .reduce(MappedResults.newSetInstance(), MappedResults::merge); } - private MappedResults createSignerForKeystore( + private static MappedResults createSignerForKeystore( final Path keystoreFile, final PasswordReader passwordReader) { try { LOG.debug("Loading keystore {}", keystoreFile); diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/config/DefaultArtifactSignerProvider.java b/signing/src/main/java/tech/pegasys/web3signer/signing/config/DefaultArtifactSignerProvider.java index 788cbc7b4..b77fb80d8 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/config/DefaultArtifactSignerProvider.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/config/DefaultArtifactSignerProvider.java @@ -24,10 +24,9 @@ import java.io.File; import java.nio.file.Path; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; +import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -46,7 +45,7 @@ public class DefaultArtifactSignerProvider implements ArtifactSignerProvider { private static final Logger LOG = LogManager.getLogger(); private final Supplier> artifactSignerCollectionSupplier; private final Map signers = new HashMap<>(); - private final Map> proxySigners = new HashMap<>(); + private final Map> proxySigners = new HashMap<>(); private final ExecutorService executorService = Executors.newSingleThreadExecutor(); private final Optional commitBoostKeystoresParameters; @@ -117,14 +116,14 @@ public Set availableIdentifiers() { } @Override - public Map> getProxyIdentifiers(final String identifier) { - final List artifactSigners = - proxySigners.computeIfAbsent(identifier, k -> List.of()); + public Map> getProxyIdentifiers(final String consensusPubKey) { + final Set artifactSigners = + proxySigners.computeIfAbsent(consensusPubKey, k -> Set.of()); return artifactSigners.stream() .collect( Collectors.groupingBy( ArtifactSigner::getKeyType, - Collectors.mapping(ArtifactSigner::getIdentifier, Collectors.toList()))); + Collectors.mapping(ArtifactSigner::getIdentifier, Collectors.toSet()))); } @Override @@ -142,6 +141,7 @@ public Future removeSigner(final String identifier) { return executorService.submit( () -> { signers.remove(identifier); + proxySigners.remove(identifier); LOG.info("Removed signer with identifier '{}'", identifier); return null; }); @@ -168,7 +168,7 @@ private void loadSecpProxySigners( SecpV3KeystoresBulkLoader.loadV3KeystoresUsingPasswordFileOrDir( proxySecpDir, keystoreParameter.getKeystoresPasswordFile()); final Collection secpSigners = secpSignersResults.getValues(); - proxySigners.computeIfAbsent(identifier, k -> new ArrayList<>()).addAll(secpSigners); + proxySigners.computeIfAbsent(identifier, k -> new HashSet<>()).addAll(secpSigners); } } @@ -180,12 +180,11 @@ private void loadBlsProxySigners( if (canReadFromDirectory(proxyBlsDir)) { // load bls proxy signers - final BlsKeystoreBulkLoader blsKeystoreBulkLoader = new BlsKeystoreBulkLoader(); final MappedResults blsSignersResult = - blsKeystoreBulkLoader.loadKeystoresUsingPasswordFile( + BlsKeystoreBulkLoader.loadKeystoresUsingPasswordFile( proxyBlsDir, keystoreParameter.getKeystoresPasswordFile()); final Collection blsSigners = blsSignersResult.getValues(); - proxySigners.computeIfAbsent(identifier, k -> new ArrayList<>()).addAll(blsSigners); + proxySigners.computeIfAbsent(identifier, k -> new HashSet<>()).addAll(blsSigners); } } } diff --git a/signing/src/main/java/tech/pegasys/web3signer/signing/config/SecpArtifactSignerProviderAdapter.java b/signing/src/main/java/tech/pegasys/web3signer/signing/config/SecpArtifactSignerProviderAdapter.java index 36578bcdf..1bf928e79 100644 --- a/signing/src/main/java/tech/pegasys/web3signer/signing/config/SecpArtifactSignerProviderAdapter.java +++ b/signing/src/main/java/tech/pegasys/web3signer/signing/config/SecpArtifactSignerProviderAdapter.java @@ -17,10 +17,8 @@ import tech.pegasys.web3signer.signing.ArtifactSigner; import tech.pegasys.web3signer.signing.ArtifactSignerProvider; -import tech.pegasys.web3signer.signing.KeyType; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -69,7 +67,7 @@ public Set availableIdentifiers() { } @Override - public Map> getProxyIdentifiers(final String identifier) { + public Map> getProxyIdentifiers(final String identifier) { throw new NotImplementedException(); } diff --git a/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignatureTest.java b/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignatureTest.java index f76bd0901..9f81f379d 100644 --- a/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignatureTest.java +++ b/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignatureTest.java @@ -28,7 +28,7 @@ void hexEncodedSignatureIsReturned() { final BLSSignature blsSignature = BLSSignature.fromBytesCompressed(Bytes.fromHexString(SIGNATURE)); final BlsArtifactSignature blsArtifactSignature = new BlsArtifactSignature(blsSignature); - assertThat(blsArtifactSignature.getSignatureData().toString()).isEqualTo(SIGNATURE); + assertThat(blsArtifactSignature.asHex()).isEqualTo(SIGNATURE); assertThat(blsSignature.toBytesCompressed().toHexString()).isEqualTo(SIGNATURE); assertThat(blsSignature.toString()).isEqualTo(SIGNATURE); } diff --git a/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignerTest.java b/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignerTest.java index 0abfa331b..3919fc0a4 100644 --- a/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignerTest.java +++ b/signing/src/test/java/tech/pegasys/web3signer/signing/BlsArtifactSignerTest.java @@ -45,6 +45,6 @@ void signsData() { new BlsArtifactSigner(keyPair, SignerOrigin.FILE_RAW); final BlsArtifactSignature signature = blsArtifactSigner.sign(message); - assertThat(signature.getSignatureData().toString()).isEqualTo(expectedSignature.toString()); + assertThat(signature.asHex()).isEqualTo(expectedSignature.toString()); } }