Skip to content

Commit

Permalink
Add eth_signTransaction (#822)
Browse files Browse the repository at this point in the history
* add eth_signTransaction

Signed-off-by: Gabriel Fukushima <[email protected]>

* add bouncycastle to test in the core package

Signed-off-by: Gabriel Fukushima <[email protected]>

* Update CHANGELOG.md

---------

Signed-off-by: Gabriel Fukushima <[email protected]>
  • Loading branch information
gfukushima authored Jun 29, 2023
1 parent b72477c commit 2592dec
Show file tree
Hide file tree
Showing 30 changed files with 943 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
### Features Added
- Hashicorp connection properties can now override http protocol to HTTP/1.1 from the default of HTTP/2. [#817](https://github.com/ConsenSys/web3signer/pull/817)
- Add --key-config-path as preferred alias to --key-store-path [#826](https://github.com/Consensys/web3signer/pull/826)
- Add eth_SignTransaction RPC method under the eth1 subcommand [#822](https://github.com/ConsenSys/web3signer/pull/822)

### Bugs fixed
- Support long name aliases in environment variables and YAML configuration [#825](https://github.com/Consensys/web3signer/pull/825)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import tech.pegasys.web3signer.core.config.TlsOptions;
import tech.pegasys.web3signer.core.config.client.ClientTlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ChainIdProvider;
import tech.pegasys.web3signer.dsl.tls.TlsCertificateDefinition;
import tech.pegasys.web3signer.signing.config.AwsSecretsManagerParameters;
import tech.pegasys.web3signer.signing.config.AzureKeyVaultParameters;
Expand Down Expand Up @@ -72,6 +73,7 @@ public class SignerConfiguration {
private int downstreamHttpPort;
private Optional<ClientTlsOptions> downstreamTlsOptions;
private final Duration startupTimeout;
private final ChainIdProvider chainIdProvider;

public SignerConfiguration(
final String hostname,
Expand Down Expand Up @@ -113,7 +115,8 @@ public SignerConfiguration(
final boolean keyManagerApiEnabled,
final Optional<WatermarkRepairParameters> watermarkRepairParameters,
final int downstreamHttpPort,
final Optional<ClientTlsOptions> downstreamTlsOptions) {
final Optional<ClientTlsOptions> downstreamTlsOptions,
final ChainIdProvider chainIdProvider) {
this.hostname = hostname;
this.logLevel = logLevel;
this.httpRpcPort = httpRpcPort;
Expand Down Expand Up @@ -154,6 +157,7 @@ public SignerConfiguration(
this.watermarkRepairParameters = watermarkRepairParameters;
this.downstreamHttpPort = downstreamHttpPort;
this.downstreamTlsOptions = downstreamTlsOptions;
this.chainIdProvider = chainIdProvider;
}

public String hostname() {
Expand Down Expand Up @@ -323,4 +327,8 @@ public int getDownstreamHttpPort() {
public Optional<ClientTlsOptions> getDownstreamTlsOptions() {
return downstreamTlsOptions;
}

public ChainIdProvider getChainIdProvider() {
return chainIdProvider;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
package tech.pegasys.web3signer.dsl.signer;

import static java.util.Collections.emptyList;
import static tech.pegasys.web3signer.tests.AcceptanceTestBase.DEFAULT_CHAIN_ID;

import tech.pegasys.web3signer.core.config.TlsOptions;
import tech.pegasys.web3signer.core.config.client.ClientTlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ChainIdProvider;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.tls.TlsCertificateDefinition;
import tech.pegasys.web3signer.signing.config.AwsSecretsManagerParameters;
import tech.pegasys.web3signer.signing.config.AzureKeyVaultParameters;
Expand Down Expand Up @@ -74,6 +77,8 @@ public class SignerConfigurationBuilder {
private int downstreamHttpPort;
private ClientTlsOptions downstreamTlsOptions;

private ChainIdProvider chainIdProvider = new ConfigurationChainId(DEFAULT_CHAIN_ID);

public SignerConfigurationBuilder withLogLevel(final Level logLevel) {
this.logLevel = logLevel;
return this;
Expand Down Expand Up @@ -288,6 +293,11 @@ public SignerConfigurationBuilder withDownstreamTlsOptions(
return this;
}

public SignerConfigurationBuilder withChainIdProvider(final ChainIdProvider chainIdProvider) {
this.chainIdProvider = chainIdProvider;
return this;
}

public SignerConfiguration build() {
if (mode == null) {
throw new IllegalArgumentException("Mode cannot be null");
Expand Down Expand Up @@ -332,6 +342,7 @@ public SignerConfiguration build() {
keyManagerApiEnabled,
Optional.ofNullable(watermarkRepairParameters),
downstreamHttpPort,
Optional.ofNullable(downstreamTlsOptions));
Optional.ofNullable(downstreamTlsOptions),
chainIdProvider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ public List<String> createCmdLineParams() {
yamlConfig.append(
String.format(
YAML_NUMERIC_FMT, "eth1.downstream-http-port", signerConfig.getDownstreamHttpPort()));
yamlConfig.append(
String.format(YAML_NUMERIC_FMT, "eth1.chain-id", signerConfig.getChainIdProvider().id()));
yamlConfig.append(createDownstreamTlsArgs());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ public List<String> createCmdLineParams() {
} else if (signerConfig.getMode().equals("eth1")) {
params.add("--downstream-http-port");
params.add(Integer.toString(signerConfig.getDownstreamHttpPort()));
params.add("--chain-id");
params.add(Long.toString(signerConfig.getChainIdProvider().id()));
params.addAll(createDownstreamTlsArgs());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public class AcceptanceTestBase {
protected Signer signer;
public static final String JSON_RPC_PATH = "/rpc/v0";

public static final Long FILECOIN_CHAIN_ID = 314L;
public static final Long DEFAULT_CHAIN_ID = 1337L;

protected void startSigner(final SignerConfiguration config) {
signer = new Signer(config, null);
signer.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import tech.pegasys.teku.bls.BLSKeyPair;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.web3signer.BLSTestUtil;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfiguration;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;
import tech.pegasys.web3signer.dsl.utils.Eth2RequestUtils;
Expand Down Expand Up @@ -53,6 +54,7 @@ void filecoinApisAreCounted(final boolean useConfigFile) {
.withMetricsEnabled(true)
.withMode("filecoin")
.withUseConfigFile(useConfigFile)
.withChainIdProvider(new ConfigurationChainId(FILECOIN_CHAIN_ID))
.build();
startSigner(signerConfiguration);

Expand Down Expand Up @@ -135,6 +137,7 @@ void signMetricIncrementsWhenSecpSignRequestReceived(@TempDir final Path testDir
.withMetricsEnabled(true)
.withKeyStoreDirectory(testDirectory)
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();

startSigner(signerConfiguration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import static io.restassured.RestAssured.given;

import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfiguration;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;

Expand All @@ -31,7 +32,11 @@ public class MetricsHostAllowListAcceptanceTest extends AcceptanceTestBase {
@Test
void metricsWithDefaultAllowHostsRespondsWithOkResponse() {
final SignerConfiguration signerConfiguration =
new SignerConfigurationBuilder().withMetricsEnabled(true).withMode("eth1").build();
new SignerConfigurationBuilder()
.withMetricsEnabled(true)
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();
startSigner(signerConfiguration);

given()
Expand All @@ -53,6 +58,7 @@ void metricsForAllowedHostRespondsWithOkResponse(final boolean useConfigFile) {
.withMetricsEnabled(true)
.withMode("eth1")
.withUseConfigFile(useConfigFile)
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();
startSigner(signerConfiguration);

Expand All @@ -74,6 +80,7 @@ void metricsForNonAllowedHostRespondsWithForbiddenResponse() {
.withMetricsHostAllowList(Collections.singletonList("foo"))
.withMetricsEnabled(true)
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();
startSigner(signerConfiguration);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfiguration;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;
import tech.pegasys.web3signer.dsl.utils.MetadataFileHelpers;
Expand Down Expand Up @@ -50,6 +51,7 @@ public void setup(@TempDir Path testDirectory) throws URISyntaxException {
.withKeyStoreDirectory(testDirectory)
.withMode("eth1")
.withDownstreamHttpPort(besu.ports().getHttpRpc())
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();
startSigner(web3SignerConfiguration);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import tech.pegasys.web3signer.core.config.KeyStoreOptions;
import tech.pegasys.web3signer.core.config.client.ClientTlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;
import tech.pegasys.web3signer.dsl.tls.TlsCertificateDefinition;
import tech.pegasys.web3signer.dsl.tls.client.BasicClientTlsOptions;
Expand Down Expand Up @@ -66,7 +67,10 @@ private void startSigner(
Files.writeString(workDir.resolve("clientKeystorePassword"), presentedCert.getPassword());

final Path fingerPrintFilePath = workDir.resolve("known_servers");
final SignerConfigurationBuilder builder = new SignerConfigurationBuilder().withMode("eth1");
final SignerConfigurationBuilder builder =
new SignerConfigurationBuilder()
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID));
final Optional<Integer> downstreamWeb3ServerPort =
Optional.of(Integers.valueOf(downstreamWeb3Port));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST;

import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfiguration;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;

Expand All @@ -36,6 +37,7 @@ public void proxiesRequestToWeb3Provider(@TempDir Path testDirectory) throws IOE
.withKeyStoreDirectory(testDirectory)
.withMode("eth1")
.withDownstreamHttpPort(besu.ports().getHttpRpc())
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID))
.build();
startSigner(web3SignerConfiguration);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import tech.pegasys.teku.spec.SpecMilestone;
import tech.pegasys.teku.spec.networks.Eth2Network;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;
import tech.pegasys.web3signer.tests.AcceptanceTestBase;

Expand All @@ -29,7 +30,10 @@ public class SigningAcceptanceTestBase extends AcceptanceTestBase {

protected void setupEth1Signer() {
final SignerConfigurationBuilder builder = new SignerConfigurationBuilder();
builder.withKeyStoreDirectory(testDirectory).withMode("eth1");
builder
.withKeyStoreDirectory(testDirectory)
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID));
startSigner(builder.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import static tech.pegasys.web3signer.dsl.tls.TlsClientHelper.createRequestSpecification;
import static tech.pegasys.web3signer.dsl.tls.support.CertificateHelpers.populateFingerprintFile;
import static tech.pegasys.web3signer.dsl.utils.WaitUtils.waitFor;
import static tech.pegasys.web3signer.tests.AcceptanceTestBase.DEFAULT_CHAIN_ID;

import tech.pegasys.web3signer.core.config.ClientAuthConstraints;
import tech.pegasys.web3signer.core.config.TlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.dsl.signer.Signer;
import tech.pegasys.web3signer.dsl.signer.SignerConfigurationBuilder;
import tech.pegasys.web3signer.dsl.tls.BasicTlsOptions;
Expand Down Expand Up @@ -105,7 +107,8 @@ private Signer createTlsSigner(
new SignerConfigurationBuilder()
.withHttpPort(fixedListenPort)
.withUseConfigFile(useConfigFile)
.withMode("eth1");
.withMode("eth1")
.withChainIdProvider(new ConfigurationChainId(DEFAULT_CHAIN_ID));

final ClientAuthConstraints clientAuthConstraints;
if (clientCertInServerWhitelist != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import static tech.pegasys.web3signer.commandline.DefaultCommandValues.PORT_FORMAT_HELP;
import static tech.pegasys.web3signer.commandline.util.RequiredOptionsUtil.checkIfRequiredOptionsAreInitialized;

import tech.pegasys.web3signer.commandline.annotations.RequiredOption;
import tech.pegasys.web3signer.commandline.config.client.PicoCliClientTlsOptions;
import tech.pegasys.web3signer.core.Eth1Runner;
import tech.pegasys.web3signer.core.Runner;
import tech.pegasys.web3signer.core.config.Eth1Config;
import tech.pegasys.web3signer.core.config.client.ClientTlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ChainIdProvider;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;

import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -44,6 +47,15 @@ public class Eth1SubCommand extends ModeSubCommand implements Eth1Config {

@CommandLine.Spec private CommandLine.Model.CommandSpec spec; // injected by picocli

@SuppressWarnings("FieldMayBeFinal")
@RequiredOption
@CommandLine.Option(
names = {"--chain-id"},
description = "The Chain Id that will be the intended recipient for signed transactions",
paramLabel = LONG_FORMAT_HELP,
arity = "1")
private Long chainId;

@SuppressWarnings("FieldMayBeFinal") // Because PicoCLI requires Strings to not be final.
@CommandLine.Option(
names = "--downstream-http-host",
Expand Down Expand Up @@ -187,4 +199,9 @@ public String getHttpProxyPassword() {
public Optional<ClientTlsOptions> getClientTlsOptions() {
return clientTlsOptions.isTlsEnabled() ? Optional.of(clientTlsOptions) : Optional.empty();
}

@Override
public ChainIdProvider getChainId() {
return new ConfigurationChainId(chainId);
}
}
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
testImplementation 'org.mockito:mockito-junit-jupiter'
testImplementation 'org.bouncycastle:bcprov-jdk18on'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'

integrationTestImplementation 'org.apache.logging.log4j:log4j'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import tech.pegasys.web3signer.core.jsonrpcproxy.support.RestAssuredConverter;
import tech.pegasys.web3signer.core.jsonrpcproxy.support.TestBaseConfig;
import tech.pegasys.web3signer.core.jsonrpcproxy.support.TestEth1Config;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;
import tech.pegasys.web3signer.signing.KeyType;

import java.io.File;
Expand Down Expand Up @@ -96,6 +97,8 @@ public class IntegrationTestBase {
public static final String PUBLIC_KEY_HEX_STRING =
"09b02f8a5fddd222ade4ea4528faefc399623af3f736be3c44f03e2df22fb792f3931a4d9573d333ca74343305762a753388c3422a86d98b713fc91c1ea04842";

public static final long DEFAULT_CHAIN_ID = 9;

@BeforeAll
static void setupWeb3Signer() throws Exception {
setupWeb3Signer("");
Expand All @@ -118,7 +121,8 @@ static void setupWeb3Signer(
downstreamHttpRequestPath,
LOCALHOST,
clientAndServer.getLocalPort(),
downstreamTimeout);
downstreamTimeout,
new ConfigurationChainId(DEFAULT_CHAIN_ID));
vertx = Vertx.vertx();
runner = new Eth1Runner(baseConfig, eth1Config);
runner.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import tech.pegasys.web3signer.core.config.Eth1Config;
import tech.pegasys.web3signer.core.config.client.ClientTlsOptions;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ChainIdProvider;
import tech.pegasys.web3signer.core.service.jsonrpc.handlers.signing.ConfigurationChainId;

import java.time.Duration;
import java.util.Optional;
Expand All @@ -23,16 +25,19 @@ public class TestEth1Config implements Eth1Config {
private final String downstreamHttpHost;
private final int downstreamHttpPort;
private final Duration downstreamHttpRequestTimeout;
private final ConfigurationChainId chainId;

public TestEth1Config(
final String downstreamHttpRequestPath,
final String downstreamHttpHost,
final int downstreamHttpPort,
final Duration downstreamHttpRequestTimeout) {
final Duration downstreamHttpRequestTimeout,
final ConfigurationChainId chainId) {
this.downstreamHttpRequestPath = downstreamHttpRequestPath;
this.downstreamHttpHost = downstreamHttpHost;
this.downstreamHttpPort = downstreamHttpPort;
this.downstreamHttpRequestTimeout = downstreamHttpRequestTimeout;
this.chainId = chainId;
}

@Override
Expand Down Expand Up @@ -79,4 +84,9 @@ public String getHttpProxyPassword() {
public Optional<ClientTlsOptions> getClientTlsOptions() {
return Optional.empty();
}

@Override
public ChainIdProvider getChainId() {
return chainId;
}
}
Loading

0 comments on commit 2592dec

Please sign in to comment.