From e3fb1546909276360d056cfab50c80e514bdb90b Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Tue, 23 Jul 2019 17:18:22 +1200 Subject: [PATCH 1/3] PIE-1792: Added chainId validation to PrivateTransactionValidator --- .../mainnet/MainnetProtocolSpecs.java | 20 ++- .../ethereum/mainnet/ProtocolSpecBuilder.java | 25 +++- .../privacy/PrivateTransactionHandler.java | 7 +- .../privacy/PrivateTransactionProcessor.java | 5 +- .../privacy/PrivateTransactionValidator.java | 52 ++++++- .../core/PrivateTransactionTestFixture.java | 139 ++++++++++++++++++ .../PrivateTransactionValidatorTest.java | 73 +++++++-- .../jsonrpc/JsonRpcMethodsFactory.java | 2 +- 8 files changed, 293 insertions(+), 30 deletions(-) create mode 100644 ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/PrivateTransactionTestFixture.java diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSpecs.java index a5f92bd6f1..3a1cb58bec 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSpecs.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSpecs.java @@ -29,6 +29,7 @@ import tech.pegasys.pantheon.ethereum.core.WorldUpdater; import tech.pegasys.pantheon.ethereum.mainnet.contractvalidation.MaxCodeSizeRule; import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionProcessor; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionValidator; import java.io.IOException; import java.math.BigInteger; @@ -107,7 +108,8 @@ public static ProtocolSpecBuilder frontierDefinition( (gasCalculator, transactionValidator, contractCreationProcessor, - messageCallProcessor) -> + messageCallProcessor, + privateTransactionValidator) -> new PrivateTransactionProcessor( gasCalculator, transactionValidator, @@ -115,7 +117,8 @@ public static ProtocolSpecBuilder frontierDefinition( messageCallProcessor, false, stackSizeLimit, - Account.DEFAULT_VERSION)) + Account.DEFAULT_VERSION, + new PrivateTransactionValidator(Optional.empty()))) .difficultyCalculator(MainnetDifficultyCalculators.FRONTIER) .blockHeaderValidatorBuilder(MainnetBlockHeaderValidator::create) .ommerHeaderValidatorBuilder(MainnetBlockHeaderValidator::createOmmerValidator) @@ -223,11 +226,13 @@ public static ProtocolSpecBuilder spuriousDragonDefinition( true, stackSizeLimit, Account.DEFAULT_VERSION)) + .privateTransactionValidatorBuilder(() -> new PrivateTransactionValidator(chainId)) .privateTransactionProcessorBuilder( (gasCalculator, transactionValidator, contractCreationProcessor, - messageCallProcessor) -> + messageCallProcessor, + privateTransactionValidator) -> new PrivateTransactionProcessor( gasCalculator, transactionValidator, @@ -235,7 +240,8 @@ public static ProtocolSpecBuilder spuriousDragonDefinition( messageCallProcessor, false, stackSizeLimit, - Account.DEFAULT_VERSION)) + Account.DEFAULT_VERSION, + privateTransactionValidator)) .name("SpuriousDragon"); } @@ -312,7 +318,8 @@ public static ProtocolSpecBuilder istanbulDefinition( (gasCalculator, transactionValidator, contractCreationProcessor, - messageCallProcessor) -> + messageCallProcessor, + privateTransactionValidator) -> new PrivateTransactionProcessor( gasCalculator, transactionValidator, @@ -320,7 +327,8 @@ public static ProtocolSpecBuilder istanbulDefinition( messageCallProcessor, false, stackSizeLimit, - ISTANBUL_ACCOUNT_VERSION)) + ISTANBUL_ACCOUNT_VERSION, + privateTransactionValidator)) .contractCreationProcessorBuilder( (gasCalculator, evm) -> new MainnetContractCreationProcessor( diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolSpecBuilder.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolSpecBuilder.java index bd1e241765..2a969f72f9 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolSpecBuilder.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolSpecBuilder.java @@ -24,6 +24,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.MainnetBlockProcessor.TransactionReceiptFactory; import tech.pegasys.pantheon.ethereum.mainnet.precompiles.privacy.PrivacyPrecompiledContract; import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionProcessor; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionValidator; import tech.pegasys.pantheon.ethereum.vm.EVM; import tech.pegasys.pantheon.ethereum.vm.GasCalculator; @@ -56,6 +57,7 @@ public class ProtocolSpecBuilder { private MiningBeneficiaryCalculator miningBeneficiaryCalculator; private PrivacyParameters privacyParameters; private PrivateTransactionProcessorBuilder privateTransactionProcessorBuilder; + private PrivateTransactionValidatorBuilder privateTransactionValidatorBuilder; public ProtocolSpecBuilder gasCalculator(final Supplier gasCalculatorBuilder) { this.gasCalculatorBuilder = gasCalculatorBuilder; @@ -160,6 +162,12 @@ public ProtocolSpecBuilder privateTransactionProcessorBuilder( return this; } + public ProtocolSpecBuilder privateTransactionValidatorBuilder( + final PrivateTransactionValidatorBuilder privateTransactionValidatorBuilder) { + this.privateTransactionValidatorBuilder = privateTransactionValidatorBuilder; + return this; + } + public ProtocolSpecBuilder blockProcessorBuilder( final BlockProcessorBuilder blockProcessorBuilder) { this.blockProcessorBuilder = blockProcessorBuilder; @@ -211,6 +219,7 @@ public ProtocolSpecBuilder changeConsensusContextType( .gasCalculator(gasCalculatorBuilder) .evmBuilder(evmBuilder) .transactionValidatorBuilder(transactionValidatorBuilder) + .privateTransactionValidatorBuilder(privateTransactionValidatorBuilder) .contractCreationProcessorBuilder(contractCreationProcessorBuilder) .privacyParameters(privacyParameters) .precompileContractRegistryBuilder(precompileContractRegistryBuilder) @@ -236,6 +245,7 @@ public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { checkNotNull(gasCalculatorBuilder, "Missing gasCalculator"); checkNotNull(evmBuilder, "Missing operation registry"); checkNotNull(transactionValidatorBuilder, "Missing transaction validator"); + checkNotNull(privateTransactionValidatorBuilder, "Missing private transaction validator"); checkNotNull(contractCreationProcessorBuilder, "Missing contract creation processor"); checkNotNull(precompileContractRegistryBuilder, "Missing precompile contract registry"); checkNotNull(messageCallProcessorBuilder, "Missing message call processor"); @@ -274,9 +284,15 @@ public ProtocolSpec build(final ProtocolSchedule protocolSchedule) { // Set private Tx Processor if (privacyParameters.isEnabled()) { + final PrivateTransactionValidator privateTransactionValidator = + privateTransactionValidatorBuilder.apply(); final PrivateTransactionProcessor privateTransactionProcessor = privateTransactionProcessorBuilder.apply( - gasCalculator, transactionValidator, contractCreationProcessor, messageCallProcessor); + gasCalculator, + transactionValidator, + contractCreationProcessor, + messageCallProcessor, + privateTransactionValidator); Address address = Address.privacyPrecompiled(privacyParameters.getPrivacyAddress()); PrivacyPrecompiledContract privacyPrecompiledContract = (PrivacyPrecompiledContract) @@ -332,7 +348,12 @@ PrivateTransactionProcessor apply( GasCalculator gasCalculator, TransactionValidator transactionValidator, AbstractMessageProcessor contractCreationProcessor, - AbstractMessageProcessor messageCallProcessor); + AbstractMessageProcessor messageCallProcessor, + PrivateTransactionValidator privateTransactionValidator); + } + + public interface PrivateTransactionValidatorBuilder { + PrivateTransactionValidator apply(); } public interface BlockProcessorBuilder { diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java index 11b8f6be63..4b00678831 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java @@ -31,7 +31,9 @@ import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; import tech.pegasys.pantheon.util.bytes.BytesValues; +import java.math.BigInteger; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; @@ -50,7 +52,8 @@ public class PrivateTransactionHandler { private final WorldStateArchive privateWorldStateArchive; private final PrivateTransactionValidator privateTransactionValidator; - public PrivateTransactionHandler(final PrivacyParameters privacyParameters) { + public PrivateTransactionHandler( + final PrivacyParameters privacyParameters, final Optional chainId) { this( new Enclave(privacyParameters.getEnclaveUri()), Address.privacyPrecompiled(privacyParameters.getPrivacyAddress()), @@ -58,7 +61,7 @@ public PrivateTransactionHandler(final PrivacyParameters privacyParameters) { privacyParameters.getEnclavePublicKey(), privacyParameters.getPrivateStateStorage(), privacyParameters.getPrivateWorldStateArchive(), - new PrivateTransactionValidator()); + new PrivateTransactionValidator(chainId)); } public PrivateTransactionHandler( diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionProcessor.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionProcessor.java index 7babbbdb7c..ff3ca0d794 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionProcessor.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionProcessor.java @@ -163,15 +163,16 @@ public PrivateTransactionProcessor( final AbstractMessageProcessor messageCallProcessor, final boolean clearEmptyAccounts, final int maxStackSize, - final int createContractAccountVersion) { + final int createContractAccountVersion, + final PrivateTransactionValidator privateTransactionValidator) { this.gasCalculator = gasCalculator; this.transactionValidator = transactionValidator; - this.privateTransactionValidator = new PrivateTransactionValidator(); this.contractCreationProcessor = contractCreationProcessor; this.messageCallProcessor = messageCallProcessor; this.clearEmptyAccounts = clearEmptyAccounts; this.maxStackSize = maxStackSize; this.createContractAccountVersion = createContractAccountVersion; + this.privateTransactionValidator = privateTransactionValidator; } @SuppressWarnings("unused") diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidator.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidator.java index c2b371183d..78a76b4b15 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidator.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidator.java @@ -13,20 +13,41 @@ package tech.pegasys.pantheon.ethereum.privacy; import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.INCORRECT_PRIVATE_NONCE; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.INVALID_SIGNATURE; import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.PRIVATE_NONCE_TOO_LOW; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.WRONG_CHAIN_ID; import tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason; import tech.pegasys.pantheon.ethereum.mainnet.ValidationResult; +import java.math.BigInteger; +import java.util.Optional; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -class PrivateTransactionValidator { +public class PrivateTransactionValidator { private static final Logger LOG = LogManager.getLogger(); + private final Optional chainId; + + public PrivateTransactionValidator(final Optional chainId) { + this.chainId = chainId; + } + public ValidationResult validate( final PrivateTransaction transaction, final Long accountNonce) { + + LOG.debug("Validating private transaction {} signature ", transaction.hash()); + + ValidationResult signatureValidationResult = + validateTransactionSignature(transaction); + if (!signatureValidationResult.isValid()) { + return signatureValidationResult; + } + final long transactionNonce = transaction.getNonce(); LOG.debug("Validating actual nonce {} with expected nonce {}", transactionNonce, accountNonce); @@ -49,4 +70,33 @@ public ValidationResult validate( return ValidationResult.valid(); } + + public ValidationResult validateTransactionSignature( + final PrivateTransaction transaction) { + if (chainId.isPresent() + && (transaction.getChainId().isPresent() && !transaction.getChainId().equals(chainId))) { + return ValidationResult.invalid( + WRONG_CHAIN_ID, + String.format( + "transaction was meant for chain id %s and not this chain id %s", + transaction.getChainId().get(), chainId.get())); + } + + if (!chainId.isPresent() && transaction.getChainId().isPresent()) { + return ValidationResult.invalid( + REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED, + "replay protected signatures is not supported"); + } + + // org.bouncycastle.math.ec.ECCurve.AbstractFp.decompressPoint throws an + // IllegalArgumentException for "Invalid point compression" for bad signatures. + try { + transaction.getSender(); + } catch (final IllegalArgumentException e) { + return ValidationResult.invalid( + INVALID_SIGNATURE, "sender could not be extracted from transaction signature"); + } + + return ValidationResult.valid(); + } } diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/PrivateTransactionTestFixture.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/PrivateTransactionTestFixture.java new file mode 100644 index 0000000000..4f8e647792 --- /dev/null +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/PrivateTransactionTestFixture.java @@ -0,0 +1,139 @@ +/* + * Copyright 2018 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.pantheon.ethereum.core; + +import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction; +import tech.pegasys.pantheon.ethereum.privacy.Restriction; +import tech.pegasys.pantheon.util.bytes.BytesValue; +import tech.pegasys.pantheon.util.bytes.BytesValues; + +import java.math.BigInteger; +import java.util.List; +import java.util.Optional; + +import com.google.common.collect.Lists; + +public class PrivateTransactionTestFixture { + + private long nonce = 0; + + private Wei gasPrice = Wei.of(5); + + private long gasLimit = 5000; + + private Optional
to = Optional.empty(); + private Address sender = Address.fromHexString(String.format("%020x", 1)); + + private Wei value = Wei.of(4); + + private BytesValue payload = BytesValue.EMPTY; + + private Optional chainId = Optional.of(BigInteger.valueOf(2018)); + + private BytesValue privateFrom = + BytesValues.fromBase64("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); + + private Optional> privateFor = + Optional.of( + Lists.newArrayList( + BytesValues.fromBase64("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs="))); + + private Optional privacyGroupId = Optional.empty(); + + private Restriction restriction = Restriction.RESTRICTED; + + public PrivateTransaction createTransaction(final KeyPair keys) { + final PrivateTransaction.Builder builder = PrivateTransaction.builder(); + builder + .gasLimit(gasLimit) + .gasPrice(gasPrice) + .nonce(nonce) + .payload(payload) + .value(value) + .sender(sender) + .privateFrom(privateFrom) + .restriction(restriction); + + to.ifPresent(builder::to); + chainId.ifPresent(builder::chainId); + + if (privacyGroupId.isPresent()) { + this.privacyGroupId(privacyGroupId.get()); + } else { + privateFor.ifPresent(builder::privateFor); + } + + if (privacyGroupId.isEmpty() && privateFor.isEmpty()) { + throw new IllegalArgumentException( + "Private transaction needs a privacyGroupId or privateFor field"); + } + + return builder.signAndBuild(keys); + } + + public PrivateTransactionTestFixture nonce(final long nonce) { + this.nonce = nonce; + return this; + } + + public PrivateTransactionTestFixture gasPrice(final Wei gasPrice) { + this.gasPrice = gasPrice; + return this; + } + + public PrivateTransactionTestFixture gasLimit(final long gasLimit) { + this.gasLimit = gasLimit; + return this; + } + + public PrivateTransactionTestFixture to(final Optional
to) { + this.to = to; + return this; + } + + public PrivateTransactionTestFixture sender(final Address sender) { + this.sender = sender; + return this; + } + + public PrivateTransactionTestFixture value(final Wei value) { + this.value = value; + return this; + } + + public PrivateTransactionTestFixture payload(final BytesValue payload) { + this.payload = payload; + return this; + } + + public PrivateTransactionTestFixture chainId(final Optional chainId) { + this.chainId = chainId; + return this; + } + + public PrivateTransactionTestFixture privateFrom(final BytesValue privateFrom) { + this.privateFrom = privateFrom; + return this; + } + + public PrivateTransactionTestFixture privateFor(final List privateFor) { + this.privateFor = Optional.of(privateFor); + return this; + } + + public PrivateTransactionTestFixture privacyGroupId(final BytesValue privacyGroupId) { + this.privacyGroupId = Optional.of(privacyGroupId); + return this; + } +} diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidatorTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidatorTest.java index 0f19c11b35..6ea20f354a 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidatorTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionValidatorTest.java @@ -13,27 +13,34 @@ package tech.pegasys.pantheon.ethereum.privacy; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.INCORRECT_PRIVATE_NONCE; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.INVALID_SIGNATURE; import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.PRIVATE_NONCE_TOO_LOW; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED; +import static tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.WRONG_CHAIN_ID; -import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Wei; +import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; +import tech.pegasys.pantheon.ethereum.core.PrivateTransactionTestFixture; import tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator.TransactionInvalidReason; import tech.pegasys.pantheon.ethereum.mainnet.ValidationResult; -import tech.pegasys.pantheon.util.bytes.BytesValue; import java.math.BigInteger; +import java.util.Optional; import org.junit.Before; import org.junit.Test; public class PrivateTransactionValidatorTest { + private static final KeyPair senderKeys = KeyPair.generate(); + private PrivateTransactionValidator validator; @Before public void before() { - validator = new PrivateTransactionValidator(); + validator = new PrivateTransactionValidator(Optional.empty()); } @Test @@ -60,17 +67,51 @@ public void transactionWithNonceMatchingThanAccountNonceShouldReturnValidTransac assertThat(validationResult).isEqualTo(ValidationResult.valid()); } - private static PrivateTransaction privateTransactionWithNonce(final long nonce) { - return PrivateTransaction.builder() - .nonce(nonce) - .gasPrice(Wei.of(1000)) - .gasLimit(3000000) - .to(Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57")) - .value(Wei.ZERO) - .payload(BytesValue.fromHexString("0x")) - .sender(Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73")) - .chainId(BigInteger.valueOf(2018)) - .restriction(Restriction.RESTRICTED) - .build(); + @Test + public void transactionWithInvalidChainIdShouldReturnWrongChainId() { + validator = new PrivateTransactionValidator(Optional.of(BigInteger.ONE)); + + ValidationResult validationResult = + validator.validate(privateTransactionWithChainId(999), 0L); + + assertThat(validationResult).isEqualTo(ValidationResult.invalid(WRONG_CHAIN_ID)); + } + + @Test + public void + transactionWithoutChainIdWithValidatorUsingChainIdShouldReturnReplayProtectedSignaturesNotSupported() { + validator = new PrivateTransactionValidator(Optional.empty()); + + ValidationResult validationResult = + validator.validate(privateTransactionWithChainId(999), 0L); + + assertThat(validationResult) + .isEqualTo(ValidationResult.invalid(REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED)); + } + + @Test + public void transactionWithInvalidSignatureShouldReturnInvalidSignature() { + PrivateTransaction transactionWithInvalidSignature = spy(privateTransactionWithNonce(1L)); + when(transactionWithInvalidSignature.getSender()).thenThrow(new IllegalArgumentException()); + + ValidationResult validationResult = + validator.validate(transactionWithInvalidSignature, 1L); + + assertThat(validationResult).isEqualTo(ValidationResult.invalid(INVALID_SIGNATURE)); + } + + private PrivateTransaction privateTransactionWithNonce(final long nonce) { + PrivateTransactionTestFixture privateTransactionTestFixture = + new PrivateTransactionTestFixture(); + privateTransactionTestFixture.nonce(nonce); + privateTransactionTestFixture.chainId(Optional.empty()); + return privateTransactionTestFixture.createTransaction(senderKeys); + } + + private PrivateTransaction privateTransactionWithChainId(final int chainId) { + PrivateTransactionTestFixture privateTransactionTestFixture = + new PrivateTransactionTestFixture(); + privateTransactionTestFixture.chainId(Optional.of(BigInteger.valueOf(chainId))); + return privateTransactionTestFixture.createTransaction(senderKeys); } } diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcMethodsFactory.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcMethodsFactory.java index 20acae4ae8..a5c0ddaff5 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcMethodsFactory.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcMethodsFactory.java @@ -323,7 +323,7 @@ blockchainQueries, new TransactionTracer(blockReplay), parameter), } if (rpcApis.contains(RpcApis.EEA)) { final PrivateTransactionHandler privateTransactionHandler = - new PrivateTransactionHandler(privacyParameters); + new PrivateTransactionHandler(privacyParameters, protocolSchedule.getChainId()); final Enclave enclave = new Enclave(privacyParameters.getEnclaveUri()); addMethods( enabledMethods, From 27f1efc5d042a55911ae90ba66d145bdaaec6592 Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Tue, 23 Jul 2019 17:35:47 +1200 Subject: [PATCH 2/3] Fix ProtSchedule initialisation --- .../pantheon/ethereum/mainnet/ProtocolScheduleBuilder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolScheduleBuilder.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolScheduleBuilder.java index b4ed838f48..c6d3ddb611 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolScheduleBuilder.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/ProtocolScheduleBuilder.java @@ -14,6 +14,7 @@ import tech.pegasys.pantheon.config.GenesisConfigOptions; import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionValidator; import java.math.BigInteger; import java.util.Optional; @@ -24,6 +25,7 @@ import org.apache.logging.log4j.Logger; public class ProtocolScheduleBuilder { + private static final Logger LOG = LogManager.getLogger(); private final GenesisConfigOptions config; private final Function, ProtocolSpecBuilder> protocolSpecAdapter; @@ -163,6 +165,8 @@ private void addProtocolSpec( protocolSpecAdapter .apply(definition) .privacyParameters(privacyParameters) + .privateTransactionValidatorBuilder( + () -> new PrivateTransactionValidator(protocolSchedule.getChainId())) .build(protocolSchedule))); } From efa358957d2310a48f98939e843bc994be383c00 Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Tue, 23 Jul 2019 17:50:34 +1200 Subject: [PATCH 3/3] Fix VM test init --- .../java/tech/pegasys/pantheon/ethereum/vm/VMReferenceTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/VMReferenceTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/VMReferenceTest.java index a56832286b..b144eed64c 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/VMReferenceTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/VMReferenceTest.java @@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs; import tech.pegasys.pantheon.ethereum.mainnet.MutableProtocolSchedule; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionValidator; import tech.pegasys.pantheon.ethereum.vm.ehalt.ExceptionalHaltException; import tech.pegasys.pantheon.ethereum.worldstate.DefaultMutableWorldState; import tech.pegasys.pantheon.testutil.JsonTestParameters; @@ -122,6 +123,7 @@ protected void runTest() { final ProtocolSpec protocolSpec = MainnetProtocolSpecs.frontierDefinition(OptionalInt.empty(), OptionalInt.empty()) .privacyParameters(PrivacyParameters.DEFAULT) + .privateTransactionValidatorBuilder(() -> new PrivateTransactionValidator(CHAIN_ID)) .build(new MutableProtocolSchedule<>(CHAIN_ID)); final TestBlockchain blockchain = new TestBlockchain(execEnv.getBlockHeader().getNumber());