From e4b9bf39afa7e6578fe9c2e412194bcd3140daf4 Mon Sep 17 00:00:00 2001 From: Stefan Pingel Date: Tue, 25 Jun 2019 14:38:18 +1000 Subject: [PATCH 01/17] for review --- .../pantheon/tests/web3j/RevertReason.sol | 39 ++++++++++++++ .../web3j/RevertReasonAcceptanceTest.java | 36 +++++++++++++ .../BlockTransactionSelectorTest.java | 8 ++- .../ethereum/core/TransactionReceipt.java | 53 ++++++++++++++++--- .../mainnet/MainnetProtocolSpecs.java | 10 ++-- .../mainnet/MainnetTransactionProcessor.java | 34 +++++++++--- .../mainnet/TransactionProcessor.java | 9 ++++ .../privacy/PrivateTransactionProcessor.java | 36 ++++++++++--- ...ueStoragePrefixedKeyBlockchainStorage.java | 2 +- .../ethereum/core/BlockDataGenerator.java | 15 +++--- .../core/BlockDataGeneratorWithReason.java | 25 +++++++++ .../ethereum/core/TransactionPoolTest.java | 3 +- .../ethereum/core/TransactionReceiptTest.java | 17 +++++- .../results/TransactionReceiptResult.java | 12 ++++- .../methods/EthGetTransactionReceiptTest.java | 4 +- .../logs/LogsSubscriptionServiceTest.java | 2 +- ...getTransactionReceipt_contractAddress.json | 2 +- 17 files changed, 266 insertions(+), 41 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java create mode 100644 ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol new file mode 100644 index 0000000000..cd3a07a97c --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol @@ -0,0 +1,39 @@ +/* + * 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. + */ +pragma solidity >=0.4.0 <0.6.0; + +// compile with: +// solc RevertReason.sol --bin --abi --optimize --overwrite -o . +// then create web3j wrappers with: +// web3j solidity generate -b ./generated/RevertReason.bin -a ./generated/RevertReason.abi -o ../../../../../ -p tech.pegasys.pantheon.tests.web3j.generated +contract RevertReason { + + uint public value = 0; + + function revertWithRevertReason() public { + if (true) { + revert("RevertReason"); + } else { + value = value + 1; + } + } + + function revertWithoutRevertReason() public { + if (true) { + revert(); + } else { + value = value + 1; + } + revert(); + } +} \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java new file mode 100644 index 0000000000..bc6e87b7f6 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -0,0 +1,36 @@ +/* + * 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.tests.web3j; + +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; + +public class RevertReasonAcceptanceTest extends AcceptanceTestBase { + + // private PantheonNode minerNode; + // + // @Before + // public void setUp() throws Exception { + // minerNode = pantheon.createMinerNode("miner-node"); + // cluster.start(minerNode); + // } + // + // @Test + // public void revertWithRevertReason() { + // + // final RevertReason revertReasonContract = + // minerNode.execute(transactions.createSmartContract(RevertReason.class)); + // + // final TransactionReceipt receipt = revertReasonContract.revertWithRevertReason().send(); + // send. + // } +} diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java index b7c6d247d6..2e7ac9aed6 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java @@ -54,6 +54,7 @@ import java.time.Instant; import java.util.List; +import java.util.Optional; import java.util.function.Supplier; import com.google.common.collect.Lists; @@ -121,7 +122,9 @@ public void failedTransactionsAreIncludedInTheBlock() { when(transactionProcessor.processTransaction( any(), any(), any(), eq(transaction), any(), any(), any())) - .thenReturn(MainnetTransactionProcessor.Result.failed(5, ValidationResult.valid())); + .thenReturn( + MainnetTransactionProcessor.Result.failed( + 5, ValidationResult.valid(), Optional.empty())); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState(); @@ -574,7 +577,8 @@ private Transaction createTransaction(final int transactionNumber) { // This is a duplicate of the MainnetProtocolSpec::frontierTransactionReceiptFactory private TransactionReceipt createReceipt( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { - return new TransactionReceipt(worldState.rootHash(), gasUsed, Lists.newArrayList()); + return new TransactionReceipt( + worldState.rootHash(), gasUsed, Lists.newArrayList(), Optional.empty()); } private DefaultMutableWorldState inMemoryWorldState() { diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java index 60118786f8..fed35b731f 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java @@ -15,9 +15,12 @@ import tech.pegasys.pantheon.ethereum.mainnet.TransactionReceiptType; import tech.pegasys.pantheon.ethereum.rlp.RLPInput; import tech.pegasys.pantheon.ethereum.rlp.RLPOutput; +import tech.pegasys.pantheon.util.bytes.BytesValue; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; +import java.util.Optional; import com.google.common.base.MoreObjects; @@ -42,6 +45,7 @@ public class TransactionReceipt { private final LogsBloomFilter bloomFilter; private final int status; private final TransactionReceiptType transactionReceiptType; + private final Optional revertReason; /** * Creates an instance of a state root-encoded transaction receipt. @@ -51,8 +55,11 @@ public class TransactionReceipt { * @param logs the logs generated within the transaction */ public TransactionReceipt( - final Hash stateRoot, final long cumulativeGasUsed, final List logs) { - this(stateRoot, NONEXISTENT, cumulativeGasUsed, logs); + final Hash stateRoot, + final long cumulativeGasUsed, + final List logs, + final Optional revertReason) { + this(stateRoot, NONEXISTENT, cumulativeGasUsed, logs, revertReason); } /** @@ -62,12 +69,20 @@ public TransactionReceipt( * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction */ - public TransactionReceipt(final int status, final long cumulativeGasUsed, final List logs) { - this(null, status, cumulativeGasUsed, logs); + public TransactionReceipt( + final int status, + final long cumulativeGasUsed, + final List logs, + final Optional revertReason) { + this(null, status, cumulativeGasUsed, logs, revertReason); } private TransactionReceipt( - final Hash stateRoot, final int status, final long cumulativeGasUsed, final List logs) { + final Hash stateRoot, + final int status, + final long cumulativeGasUsed, + final List logs, + final Optional revertReason) { this.stateRoot = stateRoot; this.cumulativeGasUsed = cumulativeGasUsed; this.status = status; @@ -75,6 +90,7 @@ private TransactionReceipt( this.bloomFilter = LogsBloomFilter.compute(logs); transactionReceiptType = stateRoot == null ? TransactionReceiptType.STATUS : TransactionReceiptType.ROOT; + this.revertReason = revertReason; } /** @@ -83,6 +99,14 @@ private TransactionReceipt( * @param out The RLP output to write to */ public void writeTo(final RLPOutput out) { + writeTo(out, false); + } + + public void writeToWithReason(final RLPOutput out) { + writeTo(out, true); + } + + private void writeTo(final RLPOutput out, final boolean withRevertReason) { out.startList(); // Determine whether it's a state root-encoded transaction receipt @@ -95,7 +119,9 @@ public void writeTo(final RLPOutput out) { out.writeLongScalar(cumulativeGasUsed); out.writeBytesValue(bloomFilter.getBytes()); out.writeList(logs, Log::writeTo); - + if (withRevertReason && revertReason.isPresent()) { + out.writeBytesValue(BytesValue.wrap(revertReason.get().getBytes(StandardCharsets.UTF_8))); + } out.endList(); } @@ -117,15 +143,22 @@ public static TransactionReceipt readFrom(final RLPInput input) { // TODO consider validating that the logs and bloom filter match. input.skipNext(); final List logs = input.readList(Log::readFrom); + final Optional revertReason; + if (input.isEndOfCurrentList()) { + revertReason = Optional.empty(); + } else { + final byte[] bytes = input.readBytesValue().getArrayUnsafe(); + revertReason = Optional.of(new String(bytes, StandardCharsets.UTF_8)); + } // Status code-encoded transaction receipts have a single // byte for success (0x01) or failure (0x80). if (firstElement.raw().size() == 1) { final int status = firstElement.readIntScalar(); - return new TransactionReceipt(status, cumulativeGas, logs); + return new TransactionReceipt(status, cumulativeGas, logs, revertReason); } else { final Hash stateRoot = Hash.wrap(firstElement.readBytes32()); - return new TransactionReceipt(stateRoot, cumulativeGas, logs); + return new TransactionReceipt(stateRoot, cumulativeGas, logs, revertReason); } } finally { input.leaveList(); @@ -181,6 +214,10 @@ public TransactionReceiptType getTransactionReceiptType() { return transactionReceiptType; } + public String getRevertReason() { + return revertReason.isPresent() ? revertReason.get() : null; + } + @Override public boolean equals(final Object obj) { if (obj == this) { 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 96f45d326b..a912230fd5 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 @@ -62,7 +62,7 @@ private MainnetProtocolSpecs() {} public static ProtocolSpecBuilder frontierDefinition( final OptionalInt configContractSizeLimit) { - int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT); + final int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT); return new ProtocolSpecBuilder() .gasCalculator(FrontierGasCalculator::new) .evmBuilder(MainnetEvmRegistries::frontier) @@ -113,7 +113,7 @@ public static ProtocolSpecBuilder frontierDefinition( public static ProtocolSpecBuilder homesteadDefinition( final OptionalInt configContractSizeLimit) { - int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT); + final int contractSizeLimit = configContractSizeLimit.orElse(FRONTIER_CONTRACT_SIZE_LIMIT); return frontierDefinition(configContractSizeLimit) .gasCalculator(HomesteadGasCalculator::new) .evmBuilder(MainnetEvmRegistries::homestead) @@ -238,12 +238,14 @@ public static ProtocolSpecBuilder constantinopleFixDefinition( private static TransactionReceipt frontierTransactionReceiptFactory( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { - return new TransactionReceipt(worldState.rootHash(), gasUsed, result.getLogs()); + return new TransactionReceipt( + worldState.rootHash(), gasUsed, result.getLogs(), result.getRevertReason()); } private static TransactionReceipt byzantiumTransactionReceiptFactory( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { - return new TransactionReceipt(result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs()); + return new TransactionReceipt( + result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs(), result.getRevertReason()); } private static class DaoBlockProcessor implements BlockProcessor { diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetTransactionProcessor.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetTransactionProcessor.java index fbe04d95c2..d16c454b04 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetTransactionProcessor.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetTransactionProcessor.java @@ -32,6 +32,7 @@ import java.util.ArrayDeque; import java.util.Deque; +import java.util.Optional; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -59,17 +60,30 @@ public static class Result implements TransactionProcessor.Result { private final BytesValue output; private final ValidationResult validationResult; + private final Optional revertReason; public static Result invalid( final ValidationResult validationResult) { - return new Result(Status.INVALID, LogSeries.empty(), -1, BytesValue.EMPTY, validationResult); + return new Result( + Status.INVALID, + LogSeries.empty(), + -1, + BytesValue.EMPTY, + validationResult, + Optional.empty()); } public static Result failed( final long gasRemaining, - final ValidationResult validationResult) { + final ValidationResult validationResult, + final Optional revertReason) { return new Result( - Status.FAILED, LogSeries.empty(), gasRemaining, BytesValue.EMPTY, validationResult); + Status.FAILED, + LogSeries.empty(), + gasRemaining, + BytesValue.EMPTY, + validationResult, + revertReason); } public static Result successful( @@ -77,7 +91,8 @@ public static Result successful( final long gasRemaining, final BytesValue output, final ValidationResult validationResult) { - return new Result(Status.SUCCESSFUL, logs, gasRemaining, output, validationResult); + return new Result( + Status.SUCCESSFUL, logs, gasRemaining, output, validationResult, Optional.empty()); } Result( @@ -85,12 +100,14 @@ public static Result successful( final LogSeries logs, final long gasRemaining, final BytesValue output, - final ValidationResult validationResult) { + final ValidationResult validationResult, + final Optional revertReason) { this.status = status; this.logs = logs; this.gasRemaining = gasRemaining; this.output = output; this.validationResult = validationResult; + this.revertReason = revertReason; } @Override @@ -117,6 +134,11 @@ public BytesValue getOutput() { public ValidationResult getValidationResult() { return validationResult; } + + @Override + public Optional getRevertReason() { + return revertReason; + } } private final boolean clearEmptyAccounts; @@ -289,7 +311,7 @@ public Result processTransaction( initialFrame.getOutputData(), validationResult); } else { - return Result.failed(refunded.toLong(), validationResult); + return Result.failed(refunded.toLong(), validationResult, initialFrame.getRevertReason()); } } diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java index f333defd08..a9e797857b 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java @@ -25,6 +25,8 @@ import tech.pegasys.pantheon.ethereum.vm.OperationTracer; import tech.pegasys.pantheon.util.bytes.BytesValue; +import java.util.Optional; + /** Processes transactions. */ public interface TransactionProcessor { @@ -95,6 +97,13 @@ default boolean isSuccessful() { * @return the validation result, with the reason for failure (if applicable.) */ ValidationResult getValidationResult(); + + /** + * Returns the reason a transaction was reverted (if applicable). + * + * @return the revert reason. + */ + Optional getRevertReason(); } /** 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 9676a42ed8..9bc2bde1c0 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 @@ -36,6 +36,7 @@ import java.util.ArrayDeque; import java.util.Deque; +import java.util.Optional; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -65,17 +66,30 @@ public static class Result implements TransactionProcessor.Result { private final BytesValue output; private final ValidationResult validationResult; + private final Optional revertReason; public static Result invalid( final ValidationResult validationResult) { - return new Result(Status.INVALID, LogSeries.empty(), -1, BytesValue.EMPTY, validationResult); + return new Result( + Status.INVALID, + LogSeries.empty(), + -1, + BytesValue.EMPTY, + validationResult, + Optional.empty()); } public static Result failed( final long gasRemaining, - final ValidationResult validationResult) { + final ValidationResult validationResult, + final Optional revertReason) { return new Result( - Status.FAILED, LogSeries.empty(), gasRemaining, BytesValue.EMPTY, validationResult); + Status.FAILED, + LogSeries.empty(), + gasRemaining, + BytesValue.EMPTY, + validationResult, + revertReason); } public static Result successful( @@ -83,7 +97,8 @@ public static Result successful( final long gasRemaining, final BytesValue output, final ValidationResult validationResult) { - return new Result(Status.SUCCESSFUL, logs, gasRemaining, output, validationResult); + return new Result( + Status.SUCCESSFUL, logs, gasRemaining, output, validationResult, Optional.empty()); } Result( @@ -91,12 +106,14 @@ public static Result successful( final LogSeries logs, final long gasRemaining, final BytesValue output, - final ValidationResult validationResult) { + final ValidationResult validationResult, + final Optional revertReason) { this.status = status; this.logs = logs; this.gasRemaining = gasRemaining; this.output = output; this.validationResult = validationResult; + this.revertReason = revertReason; } @Override @@ -123,6 +140,11 @@ public BytesValue getOutput() { public ValidationResult getValidationResult() { return validationResult; } + + @Override + public Optional getRevertReason() { + return revertReason; + } } @SuppressWarnings("unused") @@ -240,7 +262,9 @@ public Result processTransaction( initialFrame.getLogs(), 0, initialFrame.getOutputData(), ValidationResult.valid()); } else { return Result.failed( - 0, ValidationResult.invalid(TransactionInvalidReason.PRIVATE_TRANSACTION_FAILED)); + 0, + ValidationResult.invalid(TransactionInvalidReason.PRIVATE_TRANSACTION_FAILED), + initialFrame.getRevertReason()); } } diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java index 27979c9748..caf7b0a718 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java @@ -201,7 +201,7 @@ private void remove(final BytesValue prefix, final BytesValue key) { } private BytesValue rlpEncode(final List receipts) { - return RLP.encode(o -> o.writeList(receipts, TransactionReceipt::writeTo)); + return RLP.encode(o -> o.writeList(receipts, TransactionReceipt::writeToWithReason)); } } } diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java index 4cb78513a6..5d0e2d8a2a 100644 --- a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java @@ -107,16 +107,16 @@ private List createRandomAccounts( final int count, final float percentContractAccounts, final float percentContractAccountsWithNonEmptyStorage) { - WorldUpdater updater = worldState.updater(); - List accounts = new ArrayList<>(count); + final WorldUpdater updater = worldState.updater(); + final List accounts = new ArrayList<>(count); for (int i = 0; i < count; i++) { - MutableAccount account = updater.getOrCreate(address()); + final MutableAccount account = updater.getOrCreate(address()); if (random.nextFloat() < percentContractAccounts) { // Some percentage of accounts are contract accounts account.setCode(bytesValue(5, 50)); if (random.nextFloat() < percentContractAccountsWithNonEmptyStorage) { // Add some storage for contract accounts - int storageValues = random.nextInt(20) + 10; + final int storageValues = random.nextInt(20) + 10; for (int j = 0; j < storageValues; j++) { account.setStorageValue(uint256(), uint256()); } @@ -139,8 +139,8 @@ public List blockSequence(final int count) { public List blockSequence(final Block previousBlock, final int count) { final WorldStateArchive worldState = createInMemoryWorldStateArchive(); - Hash parentHash = previousBlock.getHeader().getHash(); - long blockNumber = previousBlock.getHeader().getNumber() + 1; + final Hash parentHash = previousBlock.getHeader().getHash(); + final long blockNumber = previousBlock.getHeader().getNumber() + 1; return blockSequence( count, blockNumber, @@ -254,7 +254,8 @@ public Transaction transaction() { } public TransactionReceipt receipt(final long cumulativeGasUsed) { - return new TransactionReceipt(hash(), cumulativeGasUsed, Arrays.asList(log(), log())); + return new TransactionReceipt( + hash(), cumulativeGasUsed, Arrays.asList(log(), log()), Optional.empty()); } public TransactionReceipt receipt() { diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java new file mode 100644 index 0000000000..fb4ebba8be --- /dev/null +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java @@ -0,0 +1,25 @@ +/* + * Copyright 2019 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 java.util.Arrays; +import java.util.Optional; + +public class BlockDataGeneratorWithReason extends BlockDataGenerator { + + @Override + public TransactionReceipt receipt(final long cumulativeGasUsed) { + return new TransactionReceipt( + hash(), cumulativeGasUsed, Arrays.asList(log(), log()), Optional.of("Reason")); + } +} diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java index 09bf466a66..f269c411ef 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java @@ -48,6 +48,7 @@ import tech.pegasys.pantheon.util.uint.UInt256; import java.util.List; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -432,7 +433,7 @@ private Block appendBlock( new BlockBody(transactionList, emptyList())); final List transactionReceipts = transactionList.stream() - .map(transaction -> new TransactionReceipt(1, 1, emptyList())) + .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) .collect(toList()); blockchain.appendBlock(block, transactionReceipts); return block; diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java index 822a50c217..15c7d20526 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java @@ -25,7 +25,22 @@ public void toFromRlp() { final BlockDataGenerator gen = new BlockDataGenerator(); final TransactionReceipt receipt = gen.receipt(); final TransactionReceipt copy = - TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeTo))); + TransactionReceipt.readFrom( + RLP.input( + RLP.encode( + receipt + ::writeToWithReason))); // STEFAN: needs to write the "reason" if available. + // We will + // have to add a test with a reason!!!! + assertEquals(receipt, copy); + } + + @Test + public void toFromRlpWithReason() { + final BlockDataGenerator gen = new BlockDataGeneratorWithReason(); + final TransactionReceipt receipt = gen.receipt(); + final TransactionReceipt copy = + TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeToWithReason))); assertEquals(receipt, copy); } } diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java index 0010ba17f7..7b11adccd8 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java @@ -23,6 +23,7 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonPropertyOrder({ @@ -38,7 +39,8 @@ "status", "to", "transactionHash", - "transactionIndex" + "transactionIndex", + "revertReason" }) public abstract class TransactionReceiptResult { @@ -53,6 +55,7 @@ public abstract class TransactionReceiptResult { private final String to; private final String transactionHash; private final String transactionIndex; + private final String revertReason; protected final TransactionReceipt receipt; @@ -78,6 +81,7 @@ public TransactionReceiptResult(final TransactionReceiptWithMetadata receiptWith this.to = receiptWithMetadata.getTransaction().getTo().map(BytesValue::toString).orElse(null); this.transactionHash = receiptWithMetadata.getTransaction().hash().toString(); this.transactionIndex = Quantity.create(receiptWithMetadata.getTransactionIndex()); + this.revertReason = receipt.getRevertReason(); } @JsonGetter(value = "blockHash") @@ -135,6 +139,12 @@ public String getTransactionIndex() { return transactionIndex; } + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonGetter(value = "revertReason") + public String getRevertReason() { + return revertReason; + } + private List logReceipts( final List logs, final long blockNumber, diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java index ae6a79aac1..e3f1810101 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java @@ -44,11 +44,11 @@ public class EthGetTransactionReceiptTest { private final TransactionReceipt stateReceipt = - new TransactionReceipt(1, 12, Collections.emptyList()); + new TransactionReceipt(1, 12, Collections.emptyList(), Optional.empty()); private final Hash stateRoot = Hash.fromHexString("0000000000000000000000000000000000000000000000000000000000000000"); private final TransactionReceipt rootReceipt = - new TransactionReceipt(stateRoot, 12, Collections.emptyList()); + new TransactionReceipt(stateRoot, 12, Collections.emptyList(), Optional.empty()); private final Signature signature = Signature.create(BigInteger.ONE, BigInteger.TEN, (byte) 1); private final Address sender = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/logs/LogsSubscriptionServiceTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/logs/LogsSubscriptionServiceTest.java index 5e791e2eae..bb3ef49f7b 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/logs/LogsSubscriptionServiceTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/logs/LogsSubscriptionServiceTest.java @@ -192,7 +192,7 @@ private TransactionReceiptWithMetadata createTransactionWithLog( final Transaction transaction, final Log log) { final BlockHeader blockHeader = blockHeaderTestFixture.buildHeader(); final TransactionReceipt transactionReceipt = - new TransactionReceipt(Hash.ZERO, 1L, Lists.newArrayList(log)); + new TransactionReceipt(Hash.ZERO, 1L, Lists.newArrayList(log), Optional.empty()); final TransactionReceiptWithMetadata transactionReceiptWithMetadata = TransactionReceiptWithMetadata.create( transactionReceipt, diff --git a/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json index c64b099a4b..0e84473fc7 100644 --- a/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json +++ b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json @@ -26,4 +26,4 @@ } }, "statusCode": 200 -} \ No newline at end of file +} From 4cac6f9f33015618e6083d1408fb606f2759c822 Mon Sep 17 00:00:00 2001 From: Stefan Pingel Date: Sat, 29 Jun 2019 00:51:22 +1000 Subject: [PATCH 02/17] revert reason can be disabled now --- .../tests/acceptance/dsl/ContractUtils.java | 54 ++++++ .../dsl/condition/eth/EthConditions.java | 20 ++ ...fulEthGetTransactionReceiptWithReason.java | 35 ++++ ...EthGetTransactionReceiptWithoutReason.java | 35 ++++ .../acceptance/dsl/node/PantheonNode.java | 17 +- .../dsl/node/ThreadPantheonNodeRunner.java | 4 + .../node/configuration/NodeConfiguration.java | 2 + ...nsactionReceiptRawResponseTransaction.java | 92 +++++++++ .../dsl/transaction/eth/EthTransactions.java | 10 + .../web3j/RevertReasonAcceptanceTest.java | 70 +++++-- .../tests/web3j/generated/RevertReason.abi | 1 + .../tests/web3j/generated/RevertReason.bin | 1 + .../tests/web3j/generated/RevertReason.java | 179 ++++++++++++++++++ .../clique/CliqueProtocolSchedule.java | 12 +- .../clique/CliqueProtocolScheduleTest.java | 5 +- .../blockcreation/CliqueBlockCreatorTest.java | 2 +- .../CliqueMinerExecutorTest.java | 6 +- .../consensus/ibft/IbftProtocolSchedule.java | 14 +- .../ibftlegacy/IbftProtocolSchedule.java | 12 +- .../blockcreation/IbftBlockCreatorTest.java | 3 +- .../EthHashBlockCreatorTest.java | 3 +- .../ethereum/core/TransactionReceipt.java | 22 ++- .../FixedDifficultyProtocolSchedule.java | 14 +- .../mainnet/MainnetProtocolSchedule.java | 27 ++- .../mainnet/MainnetProtocolSpecs.java | 30 ++- .../mainnet/ProtocolScheduleBuilder.java | 35 +++- ...ueStoragePrefixedKeyBlockchainStorage.java | 2 +- .../ethereum/core/BlockDataGenerator.java | 12 +- .../core/ExecutionContextTestFixture.java | 3 +- .../ethereum/core/TransactionReceiptTest.java | 10 +- .../fixed/FixedProtocolScheduleTest.java | 4 +- .../mainnet/MainnetProtocolScheduleTest.java | 4 +- .../vm/ReferenceTestProtocolSchedules.java | 2 +- .../eth/messages/ReceiptsMessage.java | 2 +- .../eth/messages/BlockBodiesMessageTest.java | 2 +- .../eth/messages/BlockHeadersMessageTest.java | 2 +- .../eth/sync/ChainHeadTrackerTest.java | 3 +- .../ethereum/eth/transactions/TestNode.java | 3 +- .../EthGetFilterChangesIntegrationTest.java | 3 +- .../results/TransactionReceiptResult.java | 2 +- ...getTransactionReceipt_contractAddress.json | 2 +- .../pegasys/pantheon/cli/PantheonCommand.java | 7 + .../CliquePantheonControllerBuilder.java | 2 +- .../IbftLegacyPantheonControllerBuilder.java | 3 +- .../IbftPantheonControllerBuilder.java | 3 +- .../MainnetPantheonControllerBuilder.java | 3 +- .../controller/PantheonControllerBuilder.java | 6 + .../pantheon/cli/CommandTestAbstract.java | 1 + .../src/test/resources/everything_config.toml | 3 + 49 files changed, 690 insertions(+), 99 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java new file mode 100644 index 0000000000..0f48aaecc5 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 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.tests.acceptance.dsl; + +import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; + +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.JsonRpc2_0Web3j; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.tx.RawTransactionManager; + +@SuppressWarnings("rawtypes") +public class ContractUtils { + + private static final BigInteger GAS_PRICE = BigInteger.valueOf(1000); + private static final BigInteger GAS_LIMIT = BigInteger.valueOf(3000000); + private static final Credentials BENEFACTOR_ONE = + Credentials.create(Accounts.GENESIS_ACCOUNT_ONE_PRIVATE_KEY); + + public static EthSendTransaction sendWithRevert( + final String functionName, final String contractAddress, final Web3jService web3jService) + throws IOException { + final Function function = + new Function( + functionName, Arrays.asList(), Collections.>emptyList()); + + final Web3j web3j = new JsonRpc2_0Web3j(web3jService); + final RawTransactionManager transactionManager = + new RawTransactionManager(web3j, BENEFACTOR_ONE); + return transactionManager.sendTransaction( + GAS_PRICE, GAS_LIMIT, contractAddress, FunctionEncoder.encode(function), BigInteger.ZERO); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java index 81fc2330a6..85d8a1b8eb 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java @@ -15,6 +15,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; +import java.util.Optional; + public class EthConditions { private final EthTransactions transactions; @@ -50,4 +52,22 @@ public Condition sendRawTransactionExceptional( return new ExpectEthSendRawTransactionException( transactions.sendRawTransactionTransaction(transactionData), expectedMessage); } + + public Condition expectSuccessfulTransactionReceiptWithReason( + final String transactionHash, + final Optional hostName, + final Optional jsonRpcHttpSocketPort) { + return new ExpectSuccessfulEthGetTransactionReceiptWithReason( + transactions.getTransactionReceiptRawResponseTransaction( + transactionHash, hostName, jsonRpcHttpSocketPort)); + } + + public Condition expectSuccessfulTransactionReceiptWithoutReason( + final String transactionHash, + final Optional hostName, + final Optional jsonRpcHttpSocketPort) { + return new ExpectSuccessfulEthGetTransactionReceiptWithoutReason( + transactions.getTransactionReceiptRawResponseTransaction( + transactionHash, hostName, jsonRpcHttpSocketPort)); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java new file mode 100644 index 0000000000..5cea8fd572 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -0,0 +1,35 @@ +/* + * 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.tests.acceptance.dsl.condition.eth; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; + +public class ExpectSuccessfulEthGetTransactionReceiptWithReason implements Condition { + + private final EthGetTransactionReceiptRawResponseTransaction transaction; + + public ExpectSuccessfulEthGetTransactionReceiptWithReason( + final EthGetTransactionReceiptRawResponseTransaction transaction) { + this.transaction = transaction; + } + + @Override + public void verify(final Node node) { + WaitUtils.waitFor(() -> assertThat(node.execute(transaction)).contains("RevertReason")); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java new file mode 100644 index 0000000000..7431589e68 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -0,0 +1,35 @@ +/* + * 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.tests.acceptance.dsl.condition.eth; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; + +public class ExpectSuccessfulEthGetTransactionReceiptWithoutReason implements Condition { + + private final EthGetTransactionReceiptRawResponseTransaction transaction; + + public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( + final EthGetTransactionReceiptRawResponseTransaction transaction) { + this.transaction = transaction; + } + + @Override + public void verify(final Node node) { + WaitUtils.waitFor(() -> assertThat(node.execute(transaction)).doesNotContain("RevertReason")); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index 21b17968e4..9c7fa9543d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -99,6 +99,7 @@ public class PantheonNode implements NodeConfiguration, RunnableNode, AutoClosea private String token = null; private final List plugins = new ArrayList<>(); private final List extraCLIOptions; + private Web3jService web3jService; public PantheonNode( final String name, @@ -239,6 +240,15 @@ public Optional getJsonRpcWebSocketPort() { } } + @Override + public Optional getJsonRpcHttpPort() { + if (isWebSocketsRpcEnabled()) { + return Optional.of(Integer.valueOf(portsProperties.getProperty("json-rpc"))); + } else { + return Optional.empty(); + } + } + @Override public String getHostName() { return LOCALHOST; @@ -247,7 +257,6 @@ public String getHostName() { private NodeRequests nodeRequests() { Optional websocketService = Optional.empty(); if (nodeRequests == null) { - final Web3jService web3jService; if (useWsForJsonRpc) { final String url = wsRpcBaseUrl().orElse("ws://" + LOCALHOST + ":" + 8546); @@ -291,6 +300,10 @@ private NodeRequests nodeRequests() { return nodeRequests; } + public Web3jService web3jService() { + return web3jService; + } + private LoginRequestFactory loginRequestFactory() { if (loginRequestFactory == null) { final Optional baseUrl; @@ -422,7 +435,7 @@ JsonRpcConfiguration jsonRpcConfiguration() { return jsonRpcConfiguration; } - Optional jsonRpcListenHost() { + public Optional jsonRpcListenHost() { if (isJsonRpcEnabled()) { return Optional.of(jsonRpcConfiguration().getHost()); } else { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index 1597ad1c87..7fdd981e49 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -102,6 +102,10 @@ public void startNode(final PantheonNode node) { final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); final PantheonControllerBuilder builder = new PantheonController.Builder().fromEthNetworkConfig(ethNetworkConfig); + if (node.getName() + .contains("withRevertReason")) { // TODO: find better way to enable the revert reason + builder.isRevertReasonEnabled(true); + } final Path tempDir = Files.createTempDir().toPath(); final PantheonController pantheonController; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java index 36621e2592..da702feba3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java @@ -30,6 +30,8 @@ public interface NodeConfiguration { Optional getJsonRpcWebSocketPort(); + Optional getJsonRpcHttpPort(); + String getHostName(); boolean isJsonRpcEnabled(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java new file mode 100644 index 0000000000..9972191155 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java @@ -0,0 +1,92 @@ +/* + * 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.tests.acceptance.dsl.transaction.eth; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import io.vertx.core.Vertx; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.HttpClientRequest; +import io.vertx.core.http.HttpMethod; + +public class EthGetTransactionReceiptRawResponseTransaction implements Transaction { + + private static final String EXCEPTION_WHEN_RETRIEVING_RECEIPT = + "Exception when retrieving receipt."; + private static final String TIMEOUT_WHILE_RETRIEVING_RECEIPT = + "Timeout while retrieving receipt."; + private final String transactionHash; + private final String host; + private final Integer jsonRpcHttpSocketPort; + + public EthGetTransactionReceiptRawResponseTransaction( + final String transactioHash, + final Optional host, + final Optional jsonRpcHttpSocketPort) { + this.transactionHash = transactioHash; + this.host = host.orElse("localhost"); + this.jsonRpcHttpSocketPort = jsonRpcHttpSocketPort.orElse(8545); + } + + @Override + public String execute(final NodeRequests node) { + final Vertx vertx = Vertx.vertx(); + final CompletableFuture future = new CompletableFuture<>(); + final HttpClient httpClient = vertx.createHttpClient(); + final HttpClientRequest request = + httpClient.request( + HttpMethod.POST, + jsonRpcHttpSocketPort, + host, + "/", + rh -> + rh.bodyHandler( + bh -> { + if (rh.statusCode() == 200) { + future.complete(bh.toString()); + } else { + future.completeExceptionally( + new Exception( + "Pantheon responded with status code {" + rh.statusCode() + "}")); + } + })); + request.setChunked(false); + final String body = + "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\" :[\"" + + transactionHash + + "\"], \"id\":1}"; + request.end(body); + final String response = getResponse(future); + vertx.close(); + return response; + } + + private String getResponse(final CompletableFuture future) { + final String response; + try { + response = future.get(Integer.valueOf(10), TimeUnit.SECONDS); + } catch (final InterruptedException | ExecutionException e) { + throw new RuntimeException(EXCEPTION_WHEN_RETRIEVING_RECEIPT, e); + } catch (final TimeoutException e) { + throw new RuntimeException(TIMEOUT_WHILE_RETRIEVING_RECEIPT, e); + } + return response; + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java index 7b6f66db18..f565232b32 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java @@ -14,6 +14,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import java.util.Optional; + import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; @@ -55,4 +57,12 @@ public EthSendRawTransactionTransaction sendRawTransactionTransaction( public EthGetTransactionCountTransaction getTransactionCount(final String accountAddress) { return new EthGetTransactionCountTransaction(accountAddress); } + + public EthGetTransactionReceiptRawResponseTransaction getTransactionReceiptRawResponseTransaction( + final String transactionHash, + final Optional hostName, + final Optional jsonRpcHttpSocketPort) { + return new EthGetTransactionReceiptRawResponseTransaction( + transactionHash, hostName, jsonRpcHttpSocketPort); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index bc6e87b7f6..657f8b0e8c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -12,25 +12,61 @@ */ package tech.pegasys.pantheon.tests.web3j; +import static tech.pegasys.pantheon.tests.acceptance.dsl.ContractUtils.sendWithRevert; + import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.web3j.generated.RevertReason; + +import org.junit.Before; +import org.junit.Test; +import org.web3j.protocol.core.methods.response.EthSendTransaction; public class RevertReasonAcceptanceTest extends AcceptanceTestBase { - // private PantheonNode minerNode; - // - // @Before - // public void setUp() throws Exception { - // minerNode = pantheon.createMinerNode("miner-node"); - // cluster.start(minerNode); - // } - // - // @Test - // public void revertWithRevertReason() { - // - // final RevertReason revertReasonContract = - // minerNode.execute(transactions.createSmartContract(RevertReason.class)); - // - // final TransactionReceipt receipt = revertReasonContract.revertWithRevertReason().send(); - // send. - // } + private PantheonNode minerNode; + + @Before + public void setUp() throws Exception { + minerNode = pantheon.createMinerNode("miner-node-withRevertReason"); + cluster.start(minerNode); + } + + @Test + public void mustRevertWithRevertReason() throws Exception { + + final RevertReason revertReasonContract = + minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); + + final EthSendTransaction ethSendTransaction = + sendWithRevert( + RevertReason.FUNC_REVERTWITHREVERTREASON, + revertReasonContract.getContractAddress(), + minerNode.web3jService()); + + minerNode.verify( + eth.expectSuccessfulTransactionReceiptWithReason( + ethSendTransaction.getTransactionHash(), + minerNode.jsonRpcListenHost(), + minerNode.getJsonRpcHttpPort())); + } + + @Test + public void mustRevertWithoutRevertReason() throws Exception { + + final RevertReason revertReasonContract = + minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); + + final EthSendTransaction ethSendTransaction = + sendWithRevert( + RevertReason.FUNC_REVERTWITHOUTREVERTREASON, + revertReasonContract.getContractAddress(), + minerNode.web3jService()); + + minerNode.verify( + eth.expectSuccessfulTransactionReceiptWithoutReason( + ethSendTransaction.getTransactionHash(), + minerNode.jsonRpcListenHost(), + minerNode.getJsonRpcHttpPort())); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi new file mode 100644 index 0000000000..90d71569e0 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi @@ -0,0 +1 @@ +[{"constant":false,"inputs":[],"name":"revertWithRevertReason","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"revertWithoutRevertReason","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin new file mode 100644 index 0000000000..67ba788b46 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin @@ -0,0 +1 @@ +60806040526000805534801561001457600080fd5b5060de806100236000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806311f95f6f1460415780633fa4f245146049578063ff489d31146061575b600080fd5b60476067565b005b604f60a3565b60408051918252519081900360200190f35b6047603c565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b604482015290519081900360640190fd5b6000548156fea265627a7a72305820344bbe39744359c54d48fe55c3f74fd985bb207dd59e3b0e041c55ce0ec876cb64736f6c63430005090032 \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java new file mode 100644 index 0000000000..c0e0bc61f8 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java @@ -0,0 +1,179 @@ +/* + * Copyright 2019 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.tests.web3j.generated; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; + +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.RemoteCall; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; +import org.web3j.tx.gas.ContractGasProvider; + +/** + * Auto generated code. + * + *

Do not modify! + * + *

Please use the web3j command line tools, + * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the codegen module to update. + * + *

Generated with web3j version 4.3.0. + */ +@SuppressWarnings("rawtypes") +public class RevertReason extends Contract { + private static final String BINARY = + "60806040526000805534801561001457600080fd5b5060de806100236000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806311f95f6f1460415780633fa4f245146049578063ff489d31146061575b600080fd5b60476067565b005b604f60a3565b60408051918252519081900360200190f35b6047603c565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b604482015290519081900360640190fd5b6000548156fea265627a7a72305820344bbe39744359c54d48fe55c3f74fd985bb207dd59e3b0e041c55ce0ec876cb64736f6c63430005090032"; + + public static final String FUNC_REVERTWITHREVERTREASON = "revertWithRevertReason"; + + public static final String FUNC_VALUE = "value"; + + public static final String FUNC_REVERTWITHOUTREVERTREASON = "revertWithoutRevertReason"; + + @Deprecated + protected RevertReason( + String contractAddress, + Web3j web3j, + Credentials credentials, + BigInteger gasPrice, + BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + protected RevertReason( + String contractAddress, + Web3j web3j, + Credentials credentials, + ContractGasProvider contractGasProvider) { + super(BINARY, contractAddress, web3j, credentials, contractGasProvider); + } + + @Deprecated + protected RevertReason( + String contractAddress, + Web3j web3j, + TransactionManager transactionManager, + BigInteger gasPrice, + BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + protected RevertReason( + String contractAddress, + Web3j web3j, + TransactionManager transactionManager, + ContractGasProvider contractGasProvider) { + super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider); + } + + public RemoteCall revertWithRevertReason() { + final Function function = + new Function( + FUNC_REVERTWITHREVERTREASON, + Arrays.asList(), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public RemoteCall value() { + final Function function = + new Function( + FUNC_VALUE, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, BigInteger.class); + } + + public RemoteCall revertWithoutRevertReason() { + final Function function = + new Function( + FUNC_REVERTWITHOUTREVERTREASON, + Arrays.asList(), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + @Deprecated + public static RevertReason load( + String contractAddress, + Web3j web3j, + Credentials credentials, + BigInteger gasPrice, + BigInteger gasLimit) { + return new RevertReason(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + @Deprecated + public static RevertReason load( + String contractAddress, + Web3j web3j, + TransactionManager transactionManager, + BigInteger gasPrice, + BigInteger gasLimit) { + return new RevertReason(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static RevertReason load( + String contractAddress, + Web3j web3j, + Credentials credentials, + ContractGasProvider contractGasProvider) { + return new RevertReason(contractAddress, web3j, credentials, contractGasProvider); + } + + public static RevertReason load( + String contractAddress, + Web3j web3j, + TransactionManager transactionManager, + ContractGasProvider contractGasProvider) { + return new RevertReason(contractAddress, web3j, transactionManager, contractGasProvider); + } + + public static RemoteCall deploy( + Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) { + return deployRemoteCall( + RevertReason.class, web3j, credentials, contractGasProvider, BINARY, ""); + } + + @Deprecated + public static RemoteCall deploy( + Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(RevertReason.class, web3j, credentials, gasPrice, gasLimit, BINARY, ""); + } + + public static RemoteCall deploy( + Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) { + return deployRemoteCall( + RevertReason.class, web3j, transactionManager, contractGasProvider, BINARY, ""); + } + + @Deprecated + public static RemoteCall deploy( + Web3j web3j, + TransactionManager transactionManager, + BigInteger gasPrice, + BigInteger gasLimit) { + return deployRemoteCall( + RevertReason.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, ""); + } +} diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolSchedule.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolSchedule.java index 6fd0224f6d..dfc98d684e 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolSchedule.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolSchedule.java @@ -39,7 +39,8 @@ public class CliqueProtocolSchedule { public static ProtocolSchedule create( final GenesisConfigOptions config, final KeyPair nodeKeys, - final PrivacyParameters privacyParameters) { + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { final CliqueConfigOptions cliqueConfig = config.getCliqueConfigOptions(); @@ -52,13 +53,16 @@ public static ProtocolSchedule create( builder -> applyCliqueSpecificModifications( epochManager, cliqueConfig.getBlockPeriodSeconds(), localNodeAddress, builder), - privacyParameters) + privacyParameters, + isRevertReasonEnabled) .createProtocolSchedule(); } public static ProtocolSchedule create( - final GenesisConfigOptions config, final KeyPair nodeKeys) { - return create(config, nodeKeys, PrivacyParameters.DEFAULT); + final GenesisConfigOptions config, + final KeyPair nodeKeys, + final boolean isRevertReasonEnabled) { + return create(config, nodeKeys, PrivacyParameters.DEFAULT, isRevertReasonEnabled); } private static ProtocolSpecBuilder applyCliqueSpecificModifications( diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolScheduleTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolScheduleTest.java index fcec092441..cccaca8427 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolScheduleTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueProtocolScheduleTest.java @@ -41,7 +41,7 @@ public void protocolSpecsAreCreatedAtBlockDefinedInJson() { final GenesisConfigOptions config = GenesisConfigFile.fromConfig(jsonInput).getConfigOptions(); final ProtocolSchedule protocolSchedule = - CliqueProtocolSchedule.create(config, NODE_KEYS); + CliqueProtocolSchedule.create(config, NODE_KEYS, false); final ProtocolSpec homesteadSpec = protocolSchedule.getByBlockNumber(1); final ProtocolSpec tangerineWhistleSpec = protocolSchedule.getByBlockNumber(2); @@ -56,7 +56,8 @@ public void protocolSpecsAreCreatedAtBlockDefinedInJson() { @Test public void parametersAlignWithMainnetWithAdjustments() { final ProtocolSpec homestead = - CliqueProtocolSchedule.create(GenesisConfigFile.DEFAULT.getConfigOptions(), NODE_KEYS) + CliqueProtocolSchedule.create( + GenesisConfigFile.DEFAULT.getConfigOptions(), NODE_KEYS, false) .getByBlockNumber(0); assertThat(homestead.getName()).isEqualTo("Frontier"); diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index b3f7675468..dba0bd359c 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -75,7 +75,7 @@ public class CliqueBlockCreatorTest { public void setup() { protocolSchedule = CliqueProtocolSchedule.create( - GenesisConfigFile.DEFAULT.getConfigOptions(), proposerKeyPair); + GenesisConfigFile.DEFAULT.getConfigOptions(), proposerKeyPair, false); final Address otherAddress = Util.publicKeyToAddress(otherKeyPair.getPublicKey()); validatorList.add(otherAddress); diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index fc985806af..dfcdd97e22 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -89,7 +89,7 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() { new CliqueMinerExecutor( cliqueProtocolContext, Executors.newSingleThreadExecutor(), - CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), + CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair, false), new PendingTransactions( PendingTransactions.DEFAULT_TX_RETENTION_HOURS, 1, @@ -126,7 +126,7 @@ public void extraDataForNonEpochBlocksDoesNotContainValidaors() { new CliqueMinerExecutor( cliqueProtocolContext, Executors.newSingleThreadExecutor(), - CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), + CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair, false), new PendingTransactions( PendingTransactions.DEFAULT_TX_RETENTION_HOURS, 1, @@ -163,7 +163,7 @@ public void shouldUseLatestVanityData() { new CliqueMinerExecutor( cliqueProtocolContext, Executors.newSingleThreadExecutor(), - CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), + CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair, false), new PendingTransactions( PendingTransactions.DEFAULT_TX_RETENTION_HOURS, 1, diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftProtocolSchedule.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftProtocolSchedule.java index 02b63fb199..d9526928d2 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftProtocolSchedule.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftProtocolSchedule.java @@ -33,7 +33,9 @@ public class IbftProtocolSchedule { private static final BigInteger DEFAULT_CHAIN_ID = BigInteger.ONE; public static ProtocolSchedule create( - final GenesisConfigOptions config, final PrivacyParameters privacyParameters) { + final GenesisConfigOptions config, + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { final IbftConfigOptions ibftConfig = config.getIbftLegacyConfigOptions(); final long blockPeriod = ibftConfig.getBlockPeriodSeconds(); @@ -41,12 +43,18 @@ public static ProtocolSchedule create( config, DEFAULT_CHAIN_ID, builder -> applyIbftChanges(blockPeriod, builder), - privacyParameters) + privacyParameters, + isRevertReasonEnabled) .createProtocolSchedule(); } + public static ProtocolSchedule create( + final GenesisConfigOptions config, final boolean isRevertReasonEnabled) { + return create(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled); + } + public static ProtocolSchedule create(final GenesisConfigOptions config) { - return create(config, PrivacyParameters.DEFAULT); + return create(config, PrivacyParameters.DEFAULT, false); } private static ProtocolSpecBuilder applyIbftChanges( diff --git a/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftProtocolSchedule.java b/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftProtocolSchedule.java index 136717e511..321557b9c0 100644 --- a/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftProtocolSchedule.java +++ b/consensus/ibftlegacy/src/main/java/tech/pegasys/pantheon/consensus/ibftlegacy/IbftProtocolSchedule.java @@ -34,7 +34,9 @@ public class IbftProtocolSchedule { private static final BigInteger DEFAULT_CHAIN_ID = BigInteger.ONE; public static ProtocolSchedule create( - final GenesisConfigOptions config, final PrivacyParameters privacyParameters) { + final GenesisConfigOptions config, + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { final IbftConfigOptions ibftConfig = config.getIbftLegacyConfigOptions(); final long blockPeriod = ibftConfig.getBlockPeriodSeconds(); @@ -42,12 +44,14 @@ public static ProtocolSchedule create( config, DEFAULT_CHAIN_ID, builder -> applyIbftChanges(blockPeriod, builder), - privacyParameters) + privacyParameters, + isRevertReasonEnabled) .createProtocolSchedule(); } - public static ProtocolSchedule create(final GenesisConfigOptions config) { - return create(config, PrivacyParameters.DEFAULT); + public static ProtocolSchedule create( + final GenesisConfigOptions config, final boolean isRevertReasonEnabled) { + return create(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled); } private static ProtocolSpecBuilder applyIbftChanges( diff --git a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java index 133669ac84..050a7ca43d 100644 --- a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java +++ b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java @@ -80,7 +80,8 @@ public void headerProducedPassesValidationRules() { final ProtocolSchedule protocolSchedule = IbftProtocolSchedule.create( GenesisConfigFile.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}") - .getConfigOptions()); + .getConfigOptions(), + false); final ProtocolContext protContext = new ProtocolContext<>( blockchain, diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java index 06fc1cd707..8400036968 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java @@ -56,7 +56,8 @@ public class EthHashBlockCreatorTest { GenesisConfigFile.DEFAULT.getConfigOptions(), BigInteger.valueOf(42), Function.identity(), - PrivacyParameters.DEFAULT) + PrivacyParameters.DEFAULT, + false) .createProtocolSchedule()) .build(); diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java index 21ab4882e5..2103540492 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.core; import tech.pegasys.pantheon.ethereum.mainnet.TransactionReceiptType; +import tech.pegasys.pantheon.ethereum.rlp.RLPException; import tech.pegasys.pantheon.ethereum.rlp.RLPInput; import tech.pegasys.pantheon.ethereum.rlp.RLPOutput; import tech.pegasys.pantheon.util.bytes.BytesValue; @@ -127,7 +128,7 @@ public void writeTo(final RLPOutput out) { writeTo(out, false); } - public void writeToWithReason(final RLPOutput out) { + public void writeToWithRevertReason(final RLPOutput out) { writeTo(out, true); } @@ -154,9 +155,21 @@ private void writeTo(final RLPOutput out, final boolean withRevertReason) { * Creates a transaction receipt for the given RLP * * @param input the RLP-encoded transaction receipt + * @param b * @return the transaction receipt */ public static TransactionReceipt readFrom(final RLPInput input) { + return readFrom(input, true); + } + /** + * Creates a transaction receipt for the given RLP + * + * @param input the RLP-encoded transaction receipt + * @param revertReasonAllowed whether the rlp input is allowed to have a revert reason + * @return the transaction receipt + */ + public static TransactionReceipt readFrom( + final RLPInput input, final boolean revertReasonAllowed) { input.enterList(); try { @@ -172,6 +185,9 @@ public static TransactionReceipt readFrom(final RLPInput input) { if (input.isEndOfCurrentList()) { revertReason = Optional.empty(); } else { + if (!revertReasonAllowed) { + throw new RLPException("Unexpected value at end of TransactionReceipt"); + } final byte[] bytes = input.readBytesValue().getArrayUnsafe(); revertReason = Optional.of(new String(bytes, StandardCharsets.UTF_8)); } @@ -239,8 +255,8 @@ public TransactionReceiptType getTransactionReceiptType() { return transactionReceiptType; } - public String getRevertReason() { - return revertReason.isPresent() ? revertReason.get() : null; + public Optional getRevertReason() { + return revertReason; } @Override diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java index 24a30ab34b..d9df25023d 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedDifficultyProtocolSchedule.java @@ -21,15 +21,23 @@ public class FixedDifficultyProtocolSchedule { public static ProtocolSchedule create( - final GenesisConfigOptions config, final PrivacyParameters privacyParameters) { + final GenesisConfigOptions config, + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { return new ProtocolScheduleBuilder<>( config, builder -> builder.difficultyCalculator(FixedDifficultyCalculators.calculator(config)), - privacyParameters) + privacyParameters, + isRevertReasonEnabled) .createProtocolSchedule(); } + public static ProtocolSchedule create( + final GenesisConfigOptions config, final boolean isRevertReasonEnabled) { + return create(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled); + } + public static ProtocolSchedule create(final GenesisConfigOptions config) { - return create(config, PrivacyParameters.DEFAULT); + return create(config, PrivacyParameters.DEFAULT, false); } } diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java index cb0005f985..d003cd8a44 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java @@ -27,7 +27,8 @@ public class MainnetProtocolSchedule { public static final BigInteger DEFAULT_CHAIN_ID = BigInteger.ONE; public static ProtocolSchedule create() { - return fromConfig(GenesisConfigFile.mainnet().getConfigOptions(), PrivacyParameters.DEFAULT); + return fromConfig( + GenesisConfigFile.mainnet().getConfigOptions(), PrivacyParameters.DEFAULT, false); } /** @@ -39,15 +40,31 @@ public static ProtocolSchedule create() { * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( - final GenesisConfigOptions config, final PrivacyParameters privacyParameters) { + final GenesisConfigOptions config, + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { if (FixedDifficultyCalculators.isFixedDifficultyInConfig(config)) { - return FixedDifficultyProtocolSchedule.create(config, privacyParameters); + return FixedDifficultyProtocolSchedule.create( + config, privacyParameters, isRevertReasonEnabled); } return new ProtocolScheduleBuilder<>( - config, DEFAULT_CHAIN_ID, Function.identity(), privacyParameters) + config, DEFAULT_CHAIN_ID, Function.identity(), privacyParameters, isRevertReasonEnabled) .createProtocolSchedule(); } + /** + * Create a Mainnet protocol schedule from a config object + * + * @param config {@link GenesisConfigOptions} containing the config options for the milestone + * starting points + * @param isReverReasonEnabled + * @return A configured mainnet protocol schedule + */ + public static ProtocolSchedule fromConfig( + final GenesisConfigOptions config, final boolean isReverReasonEnabled) { + return fromConfig(config, PrivacyParameters.DEFAULT, isReverReasonEnabled); + } + /** * Create a Mainnet protocol schedule from a config object * @@ -56,6 +73,6 @@ public static ProtocolSchedule fromConfig( * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig(final GenesisConfigOptions config) { - return fromConfig(config, PrivacyParameters.DEFAULT); + return fromConfig(config, PrivacyParameters.DEFAULT, false); } } 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 27090d43fb..f4690687d5 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 @@ -224,12 +224,16 @@ public static ProtocolSpecBuilder spuriousDragonDefinition( public static ProtocolSpecBuilder byzantiumDefinition( final Optional chainId, final OptionalInt contractSizeLimit, - final OptionalInt configStackSizeLimit) { + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason) { return spuriousDragonDefinition(chainId, contractSizeLimit, configStackSizeLimit) .evmBuilder(MainnetEvmRegistries::byzantium) .precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::byzantium) .difficultyCalculator(MainnetDifficultyCalculators.BYZANTIUM) - .transactionReceiptFactory(MainnetProtocolSpecs::byzantiumTransactionReceiptFactory) + .transactionReceiptFactory( + enableRevertReason + ? MainnetProtocolSpecs::byzantiumTransactionReceiptFactoryWithReasonEnabled + : MainnetProtocolSpecs::byzantiumTransactionReceiptFactory) .blockReward(BYZANTIUM_BLOCK_REWARD) .transactionReceiptType(TransactionReceiptType.STATUS) .name("Byzantium"); @@ -238,8 +242,9 @@ public static ProtocolSpecBuilder byzantiumDefinition( public static ProtocolSpecBuilder constantinopleDefinition( final Optional chainId, final OptionalInt contractSizeLimit, - final OptionalInt configStackSizeLimit) { - return byzantiumDefinition(chainId, contractSizeLimit, configStackSizeLimit) + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason) { + return byzantiumDefinition(chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason) .difficultyCalculator(MainnetDifficultyCalculators.CONSTANTINOPLE) .gasCalculator(ConstantinopleGasCalculator::new) .evmBuilder(MainnetEvmRegistries::constantinople) @@ -250,8 +255,10 @@ public static ProtocolSpecBuilder constantinopleDefinition( public static ProtocolSpecBuilder constantinopleFixDefinition( final Optional chainId, final OptionalInt contractSizeLimit, - final OptionalInt configStackSizeLimit) { - return constantinopleDefinition(chainId, contractSizeLimit, configStackSizeLimit) + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason) { + return constantinopleDefinition( + chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason) .gasCalculator(ConstantinopleFixGasCalculator::new) .name("ConstantinopleFix"); } @@ -259,11 +266,20 @@ public static ProtocolSpecBuilder constantinopleFixDefinition( private static TransactionReceipt frontierTransactionReceiptFactory( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { return new TransactionReceipt( - worldState.rootHash(), gasUsed, result.getLogs(), result.getRevertReason()); + worldState.rootHash(), + gasUsed, + result.getLogs(), + Optional.empty()); // No revert reason in frontier } private static TransactionReceipt byzantiumTransactionReceiptFactory( final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { + return new TransactionReceipt( + result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs(), Optional.empty()); + } + + private static TransactionReceipt byzantiumTransactionReceiptFactoryWithReasonEnabled( + final TransactionProcessor.Result result, final WorldState worldState, final long gasUsed) { return new TransactionReceipt( result.isSuccessful() ? 1 : 0, gasUsed, result.getLogs(), result.getRevertReason()); } 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 89e92b062f..7fe6f79d35 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 @@ -29,31 +29,41 @@ public class ProtocolScheduleBuilder { private final Function, ProtocolSpecBuilder> protocolSpecAdapter; private final Optional defaultChainId; private final PrivacyParameters privacyParameters; + private final boolean isRevertReasonEnabled; public ProtocolScheduleBuilder( final GenesisConfigOptions config, final BigInteger defaultChainId, final Function, ProtocolSpecBuilder> protocolSpecAdapter, - final PrivacyParameters privacyParameters) { - this(config, Optional.of(defaultChainId), protocolSpecAdapter, privacyParameters); + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { + this( + config, + Optional.of(defaultChainId), + protocolSpecAdapter, + privacyParameters, + isRevertReasonEnabled); } public ProtocolScheduleBuilder( final GenesisConfigOptions config, final Function, ProtocolSpecBuilder> protocolSpecAdapter, - final PrivacyParameters privacyParameters) { - this(config, Optional.empty(), protocolSpecAdapter, privacyParameters); + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { + this(config, Optional.empty(), protocolSpecAdapter, privacyParameters, isRevertReasonEnabled); } private ProtocolScheduleBuilder( final GenesisConfigOptions config, final Optional defaultChainId, final Function, ProtocolSpecBuilder> protocolSpecAdapter, - final PrivacyParameters privacyParameters) { + final PrivacyParameters privacyParameters, + final boolean isRevertReasonEnabled) { this.config = config; this.defaultChainId = defaultChainId; this.protocolSpecAdapter = protocolSpecAdapter; this.privacyParameters = privacyParameters; + this.isRevertReasonEnabled = isRevertReasonEnabled; } public ProtocolSchedule createProtocolSchedule() { @@ -109,17 +119,26 @@ public ProtocolSchedule createProtocolSchedule() { protocolSchedule, config.getByzantiumBlockNumber(), MainnetProtocolSpecs.byzantiumDefinition( - chainId, config.getContractSizeLimit(), config.getEvmStackSize())); + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled)); addProtocolSpec( protocolSchedule, config.getConstantinopleBlockNumber(), MainnetProtocolSpecs.constantinopleDefinition( - chainId, config.getContractSizeLimit(), config.getEvmStackSize())); + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled)); addProtocolSpec( protocolSchedule, config.getConstantinopleFixBlockNumber(), MainnetProtocolSpecs.constantinopleFixDefinition( - chainId, config.getContractSizeLimit(), config.getEvmStackSize())); + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled)); LOG.info("Protocol schedule created with milestones: {}", protocolSchedule.listMilestones()); return protocolSchedule; diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java index 52889e2650..0fdf3600cf 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/storage/keyvalue/KeyValueStoragePrefixedKeyBlockchainStorage.java @@ -201,7 +201,7 @@ private void remove(final BytesValue prefix, final BytesValue key) { } private BytesValue rlpEncode(final List receipts) { - return RLP.encode(o -> o.writeList(receipts, TransactionReceipt::writeToWithReason)); + return RLP.encode(o -> o.writeList(receipts, TransactionReceipt::writeToWithRevertReason)); } } } diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java index 3e61b5baf6..43b7377d8c 100644 --- a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java @@ -111,16 +111,16 @@ private List createRandomAccounts( final int count, final float percentContractAccounts, final float percentContractAccountsWithNonEmptyStorage) { - final WorldUpdater updater = worldState.updater(); - final List accounts = new ArrayList<>(count); + WorldUpdater updater = worldState.updater(); + List accounts = new ArrayList<>(count); for (int i = 0; i < count; i++) { - final MutableAccount account = updater.getOrCreate(address()); + MutableAccount account = updater.getOrCreate(address()); if (random.nextFloat() < percentContractAccounts) { // Some percentage of accounts are contract accounts account.setCode(bytesValue(5, 50)); if (random.nextFloat() < percentContractAccountsWithNonEmptyStorage) { // Add some storage for contract accounts - final int storageValues = random.nextInt(20) + 10; + int storageValues = random.nextInt(20) + 10; for (int j = 0; j < storageValues; j++) { account.setStorageValue(uint256(), uint256()); } @@ -143,8 +143,8 @@ public List blockSequence(final int count) { public List blockSequence(final Block previousBlock, final int count) { final WorldStateArchive worldState = createInMemoryWorldStateArchive(); - final Hash parentHash = previousBlock.getHeader().getHash(); - final long blockNumber = previousBlock.getHeader().getNumber() + 1; + Hash parentHash = previousBlock.getHeader().getHash(); + long blockNumber = previousBlock.getHeader().getNumber() + 1; return blockSequence( count, blockNumber, diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/ExecutionContextTestFixture.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/ExecutionContextTestFixture.java index aed001e146..db7f06e955 100644 --- a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/ExecutionContextTestFixture.java +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/ExecutionContextTestFixture.java @@ -114,7 +114,8 @@ public ExecutionContextTestFixture build() { new StubGenesisConfigOptions().constantinopleFixBlock(0), BigInteger.valueOf(42), Function.identity(), - new PrivacyParameters()) + new PrivacyParameters(), + false) .createProtocolSchedule(); } if (keyValueStorage == null) { diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java index 15c7d20526..09c6f28354 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java @@ -25,13 +25,7 @@ public void toFromRlp() { final BlockDataGenerator gen = new BlockDataGenerator(); final TransactionReceipt receipt = gen.receipt(); final TransactionReceipt copy = - TransactionReceipt.readFrom( - RLP.input( - RLP.encode( - receipt - ::writeToWithReason))); // STEFAN: needs to write the "reason" if available. - // We will - // have to add a test with a reason!!!! + TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeToWithRevertReason)), false); assertEquals(receipt, copy); } @@ -40,7 +34,7 @@ public void toFromRlpWithReason() { final BlockDataGenerator gen = new BlockDataGeneratorWithReason(); final TransactionReceipt receipt = gen.receipt(); final TransactionReceipt copy = - TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeToWithReason))); + TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeToWithRevertReason))); assertEquals(receipt, copy); } } diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java index 82e27a3f27..df66f56073 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java @@ -17,7 +17,6 @@ import tech.pegasys.pantheon.config.GenesisConfigFile; import tech.pegasys.pantheon.ethereum.core.BlockHeader; import tech.pegasys.pantheon.ethereum.core.BlockHeaderTestFixture; -import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import org.junit.Test; @@ -28,8 +27,7 @@ public class FixedProtocolScheduleTest { public void reportedDifficultyForAllBlocksIsAFixedValue() { final ProtocolSchedule schedule = - FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.development().getConfigOptions(), PrivacyParameters.DEFAULT); + FixedDifficultyProtocolSchedule.create(GenesisConfigFile.development().getConfigOptions()); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolScheduleTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolScheduleTest.java index bf857dabe4..2626480582 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolScheduleTest.java @@ -13,7 +13,6 @@ package tech.pegasys.pantheon.ethereum.mainnet; import tech.pegasys.pantheon.config.GenesisConfigFile; -import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; import java.nio.charset.StandardCharsets; @@ -95,8 +94,7 @@ public void shouldCreateRopstenConfig() throws Exception { GenesisConfigFile.fromConfig( Resources.toString( this.getClass().getResource("/ropsten.json"), StandardCharsets.UTF_8)) - .getConfigOptions(), - PrivacyParameters.DEFAULT); + .getConfigOptions()); Assertions.assertThat(sched.getByBlockNumber(0).getName()).isEqualTo("TangerineWhistle"); Assertions.assertThat(sched.getByBlockNumber(1).getName()).isEqualTo("TangerineWhistle"); Assertions.assertThat(sched.getByBlockNumber(10).getName()).isEqualTo("SpuriousDragon"); diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/ReferenceTestProtocolSchedules.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/ReferenceTestProtocolSchedules.java index d7ee5ae2d4..8b8cff6483 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/ReferenceTestProtocolSchedules.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/vm/ReferenceTestProtocolSchedules.java @@ -66,7 +66,7 @@ public ProtocolSchedule getByName(final String name) { private static ProtocolSchedule createSchedule(final GenesisConfigOptions options) { return new ProtocolScheduleBuilder<>( - options, CHAIN_ID, Function.identity(), PrivacyParameters.DEFAULT) + options, CHAIN_ID, Function.identity(), PrivacyParameters.DEFAULT, false) .createProtocolSchedule(); } } diff --git a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/messages/ReceiptsMessage.java b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/messages/ReceiptsMessage.java index 666ff24a79..6c5015a9ae 100644 --- a/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/messages/ReceiptsMessage.java +++ b/ethereum/eth/src/main/java/tech/pegasys/pantheon/ethereum/eth/messages/ReceiptsMessage.java @@ -67,7 +67,7 @@ public List> receipts() { final int setSize = input.enterList(); final List receiptSet = new ArrayList<>(setSize); for (int i = 0; i < setSize; i++) { - receiptSet.add(TransactionReceipt.readFrom(input)); + receiptSet.add(TransactionReceipt.readFrom(input, false)); } input.leaveList(); receipts.add(receiptSet); diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockBodiesMessageTest.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockBodiesMessageTest.java index 936dd75fa2..07318cdaf6 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockBodiesMessageTest.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockBodiesMessageTest.java @@ -66,7 +66,7 @@ public void blockBodiesRoundTrip() throws IOException { message .bodies( FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.development().getConfigOptions())) + GenesisConfigFile.development().getConfigOptions(), false)) .iterator(); for (int i = 0; i < 50; ++i) { Assertions.assertThat(readBodies.next()).isEqualTo(bodies.get(i)); diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockHeadersMessageTest.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockHeadersMessageTest.java index 8267cbba36..c018da2238 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockHeadersMessageTest.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/messages/BlockHeadersMessageTest.java @@ -58,7 +58,7 @@ public void blockHeadersRoundTrip() throws IOException { final List readHeaders = message.getHeaders( FixedDifficultyProtocolSchedule.create( - GenesisConfigFile.development().getConfigOptions())); + GenesisConfigFile.development().getConfigOptions(), false)); for (int i = 0; i < 50; ++i) { Assertions.assertThat(readHeaders.get(i)).isEqualTo(headers.get(i)); diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/ChainHeadTrackerTest.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/ChainHeadTrackerTest.java index 0176519ce7..fc8c011db9 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/ChainHeadTrackerTest.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/sync/ChainHeadTrackerTest.java @@ -44,7 +44,8 @@ public class ChainHeadTrackerTest { blockchain.getChainHead().getTotalDifficulty(), 0); private final ProtocolSchedule protocolSchedule = - FixedDifficultyProtocolSchedule.create(GenesisConfigFile.development().getConfigOptions()); + FixedDifficultyProtocolSchedule.create( + GenesisConfigFile.development().getConfigOptions(), false); private final TrailingPeerLimiter trailingPeerLimiter = mock(TrailingPeerLimiter.class); private final ChainHeadTracker chainHeadTracker = diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java index d8c9c5fcf6..e7383dee52 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java @@ -93,7 +93,8 @@ public TestNode( final GenesisConfigFile genesisConfigFile = GenesisConfigFile.development(); final ProtocolSchedule protocolSchedule = - FixedDifficultyProtocolSchedule.create(GenesisConfigFile.development().getConfigOptions()); + FixedDifficultyProtocolSchedule.create( + GenesisConfigFile.development().getConfigOptions(), false); final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, protocolSchedule); final BlockHeaderFunctions blockHeaderFunctions = diff --git a/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java b/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java index a30ddf9e70..c429c7ffe1 100644 --- a/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java +++ b/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java @@ -57,6 +57,7 @@ import java.math.BigInteger; import java.util.List; +import java.util.Optional; import org.assertj.core.util.Lists; import org.junit.Before; @@ -274,7 +275,7 @@ private Block appendBlock( new BlockBody(transactionList, emptyList())); final List transactionReceipts = transactionList.stream() - .map(transaction -> new TransactionReceipt(1, 1, emptyList())) + .map(transaction -> new TransactionReceipt(1, 1, emptyList(), Optional.empty())) .collect(toList()); blockchain.appendBlock(block, transactionReceipts); return block; diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java index 7b11adccd8..77f2df95d1 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionReceiptResult.java @@ -81,7 +81,7 @@ public TransactionReceiptResult(final TransactionReceiptWithMetadata receiptWith this.to = receiptWithMetadata.getTransaction().getTo().map(BytesValue::toString).orElse(null); this.transactionHash = receiptWithMetadata.getTransaction().hash().toString(); this.transactionIndex = Quantity.create(receiptWithMetadata.getTransactionIndex()); - this.revertReason = receipt.getRevertReason(); + this.revertReason = receipt.getRevertReason().orElse(null); } @JsonGetter(value = "blockHash") diff --git a/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json index 0e84473fc7..c64b099a4b 100644 --- a/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json +++ b/ethereum/jsonrpc/src/test/resources/tech/pegasys/pantheon/ethereum/jsonrpc/eth_getTransactionReceipt_contractAddress.json @@ -26,4 +26,4 @@ } }, "statusCode": 200 -} +} \ No newline at end of file diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index 5ed6432c44..d248e2c178 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -539,6 +539,12 @@ void setBannedNodeIds(final List values) { description = "Enable private transactions (default: ${DEFAULT-VALUE})") private final Boolean isPrivacyEnabled = false; + @Option( + names = {"--revert-reason-enabled"}, + description = + "Enable passing the revert reason back through TransactionReceipts (default: ${DEFAULT-VALUE})") + private final Boolean isRevertReasonEnabled = false; + @Option( names = {"--privacy-url"}, description = "The URL on which the enclave is running") @@ -821,6 +827,7 @@ PantheonController buildController() { .metricsSystem(metricsSystem.get()) .privacyParameters(privacyParameters()) .clock(Clock.systemUTC()) + .isRevertReasonEnabled(isRevertReasonEnabled) .build(); } catch (final InvalidConfigurationException e) { throw new ExecutionException(this.commandLine, e.getMessage()); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonControllerBuilder.java index 392b570285..269b5e8427 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonControllerBuilder.java @@ -121,7 +121,7 @@ protected MiningCoordinator createMiningCoordinator( @Override protected ProtocolSchedule createProtocolSchedule() { return CliqueProtocolSchedule.create( - genesisConfig.getConfigOptions(), nodeKeys, privacyParameters); + genesisConfig.getConfigOptions(), nodeKeys, privacyParameters, isRevertReasonEnabled); } @Override diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonControllerBuilder.java index 19aad47024..cfd075571d 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonControllerBuilder.java @@ -63,7 +63,8 @@ protected MiningCoordinator createMiningCoordinator( @Override protected ProtocolSchedule createProtocolSchedule() { - return IbftProtocolSchedule.create(genesisConfig.getConfigOptions(), privacyParameters); + return IbftProtocolSchedule.create( + genesisConfig.getConfigOptions(), privacyParameters, isRevertReasonEnabled); } @Override diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonControllerBuilder.java index bd3a7111a4..e985947e52 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonControllerBuilder.java @@ -210,7 +210,8 @@ protected MiningCoordinator createMiningCoordinator( @Override protected ProtocolSchedule createProtocolSchedule() { - return IbftProtocolSchedule.create(genesisConfig.getConfigOptions(), privacyParameters); + return IbftProtocolSchedule.create( + genesisConfig.getConfigOptions(), privacyParameters, isRevertReasonEnabled); } @Override diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonControllerBuilder.java index ecfb9b9235..a77f17d5d5 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonControllerBuilder.java @@ -85,6 +85,7 @@ protected Void createConsensusContext( @Override protected ProtocolSchedule createProtocolSchedule() { - return MainnetProtocolSchedule.fromConfig(genesisConfig.getConfigOptions(), privacyParameters); + return MainnetProtocolSchedule.fromConfig( + genesisConfig.getConfigOptions(), privacyParameters, isRevertReasonEnabled); } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonControllerBuilder.java index 19349e3b8b..1651167350 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonControllerBuilder.java @@ -75,6 +75,7 @@ public abstract class PantheonControllerBuilder { protected Integer maxPendingTransactions; protected Integer pendingTransactionRetentionPeriod; protected KeyPair nodeKeys; + protected boolean isRevertReasonEnabled; private StorageProvider storageProvider; private final List shutdownActions = new ArrayList<>(); private RocksDbConfiguration rocksDbConfiguration; @@ -159,6 +160,11 @@ public PantheonControllerBuilder pendingTransactionRetentionPeriod( return this; } + public PantheonControllerBuilder isRevertReasonEnabled(final boolean isRevertReasonEnabled) { + this.isRevertReasonEnabled = isRevertReasonEnabled; + return this; + } + public PantheonController build() throws IOException { checkNotNull(genesisConfig, "Missing genesis config"); checkNotNull(syncConfig, "Missing sync config"); diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java index 896021b72e..e684dd2deb 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java @@ -138,6 +138,7 @@ public void initMocks() throws Exception { when(mockControllerBuilder.metricsSystem(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.privacyParameters(any())).thenReturn(mockControllerBuilder); when(mockControllerBuilder.clock(any())).thenReturn(mockControllerBuilder); + when(mockControllerBuilder.isRevertReasonEnabled(false)).thenReturn(mockControllerBuilder); // doReturn used because of generic PantheonController doReturn(mockController).when(mockControllerBuilder).build(); diff --git a/pantheon/src/test/resources/everything_config.toml b/pantheon/src/test/resources/everything_config.toml index ec13a72937..5835997f0a 100644 --- a/pantheon/src/test/resources/everything_config.toml +++ b/pantheon/src/test/resources/everything_config.toml @@ -97,3 +97,6 @@ privacy-precompiled-address=9 tx-pool-retention-hours=999 tx-pool-max-size=1234 + +# Revert Reaspm +revert-reason-enabled=false From e7fc10524b558db38b848ddf9d46792ff27d0632 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Mon, 1 Jul 2019 13:17:23 +1000 Subject: [PATCH 03/17] spotless --- .../blockcreation/BlockTransactionSelectorTest.java | 4 +++- .../pantheon/ethereum/core/TransactionReceipt.java | 3 ++- .../ethereum/mainnet/MainnetProtocolSchedule.java | 7 ++++--- .../ethereum/mainnet/MainnetProtocolSpecs.java | 6 ++++-- .../ethereum/mainnet/ProtocolScheduleBuilder.java | 10 ++++++++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java index 4c52f7011f..ca25240442 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java @@ -125,7 +125,9 @@ public void failedTransactionsAreIncludedInTheBlock() { when(transactionProcessor.processTransaction( any(), any(), any(), eq(transaction), any(), any(), anyBoolean(), any())) - .thenReturn(MainnetTransactionProcessor.Result.failed(5, ValidationResult.valid(), Optional.empty())); + .thenReturn( + MainnetTransactionProcessor.Result.failed( + 5, ValidationResult.valid(), Optional.empty())); // The block should fit 3 transactions only final ProcessableBlockHeader blockHeader = createBlockWithGasLimit(5000); diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java index 2103540492..8a9deee2e1 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java @@ -54,6 +54,7 @@ public class TransactionReceipt { * @param stateRoot the state root for the world state after the transaction has been processed * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction + * @param revertReason whether storing the revert reason is for failed transactions */ public TransactionReceipt( final Hash stateRoot, @@ -84,6 +85,7 @@ private TransactionReceipt( * @param status the status code for the transaction (1 for success and 0 for failure) * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction + * @param revertReason the revert reason */ public TransactionReceipt( final int status, @@ -155,7 +157,6 @@ private void writeTo(final RLPOutput out, final boolean withRevertReason) { * Creates a transaction receipt for the given RLP * * @param input the RLP-encoded transaction receipt - * @param b * @return the transaction receipt */ public static TransactionReceipt readFrom(final RLPInput input) { diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java index d003cd8a44..181203303f 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetProtocolSchedule.java @@ -37,6 +37,7 @@ public static ProtocolSchedule create() { * @param config {@link GenesisConfigOptions} containing the config options for the milestone * starting points * @param privacyParameters the parameters set for private transactions + * @param isRevertReasonEnabled whether storing the revert reason is for failed transactions * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( @@ -57,12 +58,12 @@ public static ProtocolSchedule fromConfig( * * @param config {@link GenesisConfigOptions} containing the config options for the milestone * starting points - * @param isReverReasonEnabled + * @param isRevertReasonEnabled whether storing the revert reason is for failed transactions * @return A configured mainnet protocol schedule */ public static ProtocolSchedule fromConfig( - final GenesisConfigOptions config, final boolean isReverReasonEnabled) { - return fromConfig(config, PrivacyParameters.DEFAULT, isReverReasonEnabled); + final GenesisConfigOptions config, final boolean isRevertReasonEnabled) { + return fromConfig(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled); } /** 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 dcdadb0bff..ac7f43c6b0 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 @@ -266,8 +266,10 @@ public static ProtocolSpecBuilder constantinopleFixDefinition( public static ProtocolSpecBuilder istanbulDefinition( final Optional chainId, final OptionalInt contractSizeLimit, - final OptionalInt configStackSizeLimit) { - return constantinopleFixDefinition(chainId, contractSizeLimit, configStackSizeLimit) + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason) { + return constantinopleFixDefinition( + chainId, contractSizeLimit, configStackSizeLimit, enableRevertReason) .name("Istanbul"); } 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 e51612660c..b4ed838f48 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 @@ -135,12 +135,18 @@ public ProtocolSchedule createProtocolSchedule() { protocolSchedule, config.getConstantinopleFixBlockNumber(), MainnetProtocolSpecs.constantinopleFixDefinition( - chainId, config.getContractSizeLimit(), config.getEvmStackSize(), isRevertReasonEnabled)); + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled)); addProtocolSpec( protocolSchedule, config.getIstanbulBlockNumber(), MainnetProtocolSpecs.istanbulDefinition( - chainId, config.getContractSizeLimit(), config.getEvmStackSize())); + chainId, + config.getContractSizeLimit(), + config.getEvmStackSize(), + isRevertReasonEnabled)); LOG.info("Protocol schedule created with milestones: {}", protocolSchedule.listMilestones()); return protocolSchedule; From 48f860ed847d8df1dce2dfa5abd894d4c785d071 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Mon, 1 Jul 2019 15:04:41 +1000 Subject: [PATCH 04/17] change revert reason transaction to use web3j instead of vertx so don't need start another server and avoid passing through host and ports in tests --- .../dsl/condition/eth/EthConditions.java | 17 +--- ...fulEthGetTransactionReceiptWithReason.java | 19 ++++- ...EthGetTransactionReceiptWithoutReason.java | 11 ++- .../acceptance/dsl/node/PantheonNode.java | 19 +---- .../node/configuration/NodeConfiguration.java | 2 - .../dsl/transaction/NodeRequests.java | 8 ++ ...nsactionReceiptRawResponseTransaction.java | 80 ++++--------------- .../transaction/eth/EthRawRequestFactory.java | 54 +++++++++++++ .../dsl/transaction/eth/EthTransactions.java | 9 +-- .../web3j/RevertReasonAcceptanceTest.java | 8 +- 10 files changed, 117 insertions(+), 110 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java index 85d8a1b8eb..e68ff180ce 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java @@ -15,8 +15,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; -import java.util.Optional; - public class EthConditions { private final EthTransactions transactions; @@ -54,20 +52,13 @@ public Condition sendRawTransactionExceptional( } public Condition expectSuccessfulTransactionReceiptWithReason( - final String transactionHash, - final Optional hostName, - final Optional jsonRpcHttpSocketPort) { + final String transactionHash, final String revertReason) { return new ExpectSuccessfulEthGetTransactionReceiptWithReason( - transactions.getTransactionReceiptRawResponseTransaction( - transactionHash, hostName, jsonRpcHttpSocketPort)); + transactions.getTransactionReceiptRawResponseTransaction(transactionHash), revertReason); } - public Condition expectSuccessfulTransactionReceiptWithoutReason( - final String transactionHash, - final Optional hostName, - final Optional jsonRpcHttpSocketPort) { + public Condition expectSuccessfulTransactionReceiptWithoutReason(final String transactionHash) { return new ExpectSuccessfulEthGetTransactionReceiptWithoutReason( - transactions.getTransactionReceiptRawResponseTransaction( - transactionHash, hostName, jsonRpcHttpSocketPort)); + transactions.getTransactionReceiptRawResponseTransaction(transactionHash)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java index 5cea8fd572..68a0ba1a1b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -18,18 +18,33 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; + +import java.util.Optional; public class ExpectSuccessfulEthGetTransactionReceiptWithReason implements Condition { private final EthGetTransactionReceiptRawResponseTransaction transaction; + private final String expectedRevertReason; public ExpectSuccessfulEthGetTransactionReceiptWithReason( - final EthGetTransactionReceiptRawResponseTransaction transaction) { + final EthGetTransactionReceiptRawResponseTransaction transaction, + final String expectedRevertReason) { this.transaction = transaction; + this.expectedRevertReason = expectedRevertReason; } @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(transaction)).contains("RevertReason")); + WaitUtils.waitFor( + () -> assertThat(revertReasonMatches(node, expectedRevertReason)).isPresent()); + } + + private Optional revertReasonMatches( + final Node node, final String expectedRevertReason) { + return node.execute(transaction) + .filter( + transactionReceipt -> + transactionReceipt.getRevertReason().contains(expectedRevertReason)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java index 7431589e68..b00348a7ef 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -18,6 +18,9 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; + +import java.util.Optional; public class ExpectSuccessfulEthGetTransactionReceiptWithoutReason implements Condition { @@ -30,6 +33,12 @@ public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(transaction)).doesNotContain("RevertReason")); + WaitUtils.waitFor(() -> assertThat(revertReasonIsEmpty(node)).isPresent()); + } + + private Optional revertReasonIsEmpty(final Node node) { + return node.execute(transaction) + .map(TransactionReceiptRaw::getRevertReason) + .filter(String::isEmpty); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index 9c7fa9543d..f9eb735f18 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -34,6 +34,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.admin.AdminRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomNetJsonRpcRequestFactory; @@ -99,7 +100,6 @@ public class PantheonNode implements NodeConfiguration, RunnableNode, AutoClosea private String token = null; private final List plugins = new ArrayList<>(); private final List extraCLIOptions; - private Web3jService web3jService; public PantheonNode( final String name, @@ -240,15 +240,6 @@ public Optional getJsonRpcWebSocketPort() { } } - @Override - public Optional getJsonRpcHttpPort() { - if (isWebSocketsRpcEnabled()) { - return Optional.of(Integer.valueOf(portsProperties.getProperty("json-rpc"))); - } else { - return Optional.empty(); - } - } - @Override public String getHostName() { return LOCALHOST; @@ -257,6 +248,7 @@ public String getHostName() { private NodeRequests nodeRequests() { Optional websocketService = Optional.empty(); if (nodeRequests == null) { + final Web3jService web3jService; if (useWsForJsonRpc) { final String url = wsRpcBaseUrl().orElse("ws://" + LOCALHOST + ":" + 8546); @@ -287,6 +279,7 @@ private NodeRequests nodeRequests() { nodeRequests = new NodeRequests( new JsonRpc2_0Web3j(web3jService, 2000, Async.defaultExecutorService()), + new EthRawRequestFactory(web3jService), new CliqueRequestFactory(web3jService), new Ibft2RequestFactory(web3jService), new PermissioningJsonRpcRequestFactory(web3jService), @@ -300,10 +293,6 @@ private NodeRequests nodeRequests() { return nodeRequests; } - public Web3jService web3jService() { - return web3jService; - } - private LoginRequestFactory loginRequestFactory() { if (loginRequestFactory == null) { final Optional baseUrl; @@ -435,7 +424,7 @@ JsonRpcConfiguration jsonRpcConfiguration() { return jsonRpcConfiguration; } - public Optional jsonRpcListenHost() { + Optional jsonRpcListenHost() { if (isJsonRpcEnabled()) { return Optional.of(jsonRpcConfiguration().getHost()); } else { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java index da702feba3..36621e2592 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java @@ -30,8 +30,6 @@ public interface NodeConfiguration { Optional getJsonRpcWebSocketPort(); - Optional getJsonRpcHttpPort(); - String getHostName(); boolean isJsonRpcEnabled(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java index c375901a0a..b517c89c50 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java @@ -15,6 +15,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.admin.AdminRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomNetJsonRpcRequestFactory; @@ -28,6 +29,7 @@ public class NodeRequests { private final JsonRpc2_0Web3j netEth; + private final EthRawRequestFactory ethRaw; private final CliqueRequestFactory clique; private final Ibft2RequestFactory ibft; private final PermissioningJsonRpcRequestFactory perm; @@ -39,6 +41,7 @@ public class NodeRequests { public NodeRequests( final JsonRpc2_0Web3j netEth, + final EthRawRequestFactory ethRaw, final CliqueRequestFactory clique, final Ibft2RequestFactory ibft, final PermissioningJsonRpcRequestFactory perm, @@ -48,6 +51,7 @@ public NodeRequests( final Optional websocketService, final LoginRequestFactory login) { this.netEth = netEth; + this.ethRaw = ethRaw; this.clique = clique; this.ibft = ibft; this.perm = perm; @@ -62,6 +66,10 @@ public JsonRpc2_0Web3j eth() { return netEth; } + public EthRawRequestFactory ethRaw() { + return ethRaw; + } + public JsonRpc2_0Web3j net() { return netEth; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java index 9972191155..7e89651072 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java @@ -12,81 +12,33 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth; +import static org.assertj.core.api.Assertions.assertThat; + import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.EthGetTransactionReceiptRawResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; +import java.io.IOException; import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import io.vertx.core.Vertx; -import io.vertx.core.http.HttpClient; -import io.vertx.core.http.HttpClientRequest; -import io.vertx.core.http.HttpMethod; - -public class EthGetTransactionReceiptRawResponseTransaction implements Transaction { - private static final String EXCEPTION_WHEN_RETRIEVING_RECEIPT = - "Exception when retrieving receipt."; - private static final String TIMEOUT_WHILE_RETRIEVING_RECEIPT = - "Timeout while retrieving receipt."; +public class EthGetTransactionReceiptRawResponseTransaction + implements Transaction> { private final String transactionHash; - private final String host; - private final Integer jsonRpcHttpSocketPort; - public EthGetTransactionReceiptRawResponseTransaction( - final String transactioHash, - final Optional host, - final Optional jsonRpcHttpSocketPort) { - this.transactionHash = transactioHash; - this.host = host.orElse("localhost"); - this.jsonRpcHttpSocketPort = jsonRpcHttpSocketPort.orElse(8545); + public EthGetTransactionReceiptRawResponseTransaction(final String transactionHash) { + this.transactionHash = transactionHash; } @Override - public String execute(final NodeRequests node) { - final Vertx vertx = Vertx.vertx(); - final CompletableFuture future = new CompletableFuture<>(); - final HttpClient httpClient = vertx.createHttpClient(); - final HttpClientRequest request = - httpClient.request( - HttpMethod.POST, - jsonRpcHttpSocketPort, - host, - "/", - rh -> - rh.bodyHandler( - bh -> { - if (rh.statusCode() == 200) { - future.complete(bh.toString()); - } else { - future.completeExceptionally( - new Exception( - "Pantheon responded with status code {" + rh.statusCode() + "}")); - } - })); - request.setChunked(false); - final String body = - "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\" :[\"" - + transactionHash - + "\"], \"id\":1}"; - request.end(body); - final String response = getResponse(future); - vertx.close(); - return response; - } - - private String getResponse(final CompletableFuture future) { - final String response; + public Optional execute(final NodeRequests node) { try { - response = future.get(Integer.valueOf(10), TimeUnit.SECONDS); - } catch (final InterruptedException | ExecutionException e) { - throw new RuntimeException(EXCEPTION_WHEN_RETRIEVING_RECEIPT, e); - } catch (final TimeoutException e) { - throw new RuntimeException(TIMEOUT_WHILE_RETRIEVING_RECEIPT, e); + final EthGetTransactionReceiptRawResponse response = + node.ethRaw().ethGetTransactionReceiptRaw(transactionHash).send(); + assertThat(response.hasError()).isFalse(); + return Optional.ofNullable(response.getResult()); + } catch (final IOException e) { + throw new RuntimeException(e); } - return response; } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java new file mode 100644 index 0000000000..16338b621c --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 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.tests.acceptance.dsl.transaction.eth; + +import java.util.Arrays; + +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +public class EthRawRequestFactory { + + public static class TransactionReceiptRaw extends TransactionReceipt { + private String revertReason; + + public TransactionReceiptRaw() {} + + public void setRevertReason(final String revertReason) { + this.revertReason = revertReason; + } + + public String getRevertReason() { + return revertReason; + } + } + + public static class EthGetTransactionReceiptRawResponse extends Response {} + + private final Web3jService web3jService; + + public EthRawRequestFactory(final Web3jService web3jService) { + this.web3jService = web3jService; + } + + public Request ethGetTransactionReceiptRaw( + String transactionHash) { + return new Request<>( + "eth_getTransactionReceipt", + Arrays.asList(transactionHash), + web3jService, + EthGetTransactionReceiptRawResponse.class); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java index f565232b32..c54efd37d0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java @@ -14,8 +14,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; -import java.util.Optional; - import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; @@ -59,10 +57,7 @@ public EthGetTransactionCountTransaction getTransactionCount(final String accoun } public EthGetTransactionReceiptRawResponseTransaction getTransactionReceiptRawResponseTransaction( - final String transactionHash, - final Optional hostName, - final Optional jsonRpcHttpSocketPort) { - return new EthGetTransactionReceiptRawResponseTransaction( - transactionHash, hostName, jsonRpcHttpSocketPort); + final String transactionHash) { + return new EthGetTransactionReceiptRawResponseTransaction(transactionHash); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index 657f8b0e8c..cde329dd71 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -46,9 +46,7 @@ public void mustRevertWithRevertReason() throws Exception { minerNode.verify( eth.expectSuccessfulTransactionReceiptWithReason( - ethSendTransaction.getTransactionHash(), - minerNode.jsonRpcListenHost(), - minerNode.getJsonRpcHttpPort())); + ethSendTransaction.getTransactionHash(), "RevertReason")); } @Test @@ -65,8 +63,6 @@ public void mustRevertWithoutRevertReason() throws Exception { minerNode.verify( eth.expectSuccessfulTransactionReceiptWithoutReason( - ethSendTransaction.getTransactionHash(), - minerNode.jsonRpcListenHost(), - minerNode.getJsonRpcHttpPort())); + ethSendTransaction.getTransactionHash())); } } From 7b4cc75826869d64459fd1944d99f060038cf57b Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Mon, 1 Jul 2019 17:01:37 +1000 Subject: [PATCH 05/17] create transaction to call a smart contract function that reverts so don't need to expose web3j --- .../CallSmartContractFunctionWithRevert.java} | 40 ++++++++++--------- .../contract/ContractTransactions.java | 6 +++ .../web3j/RevertReasonAcceptanceTest.java | 36 +++++++---------- 3 files changed, 41 insertions(+), 41 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/{ContractUtils.java => transaction/CallSmartContractFunctionWithRevert.java} (59%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java similarity index 59% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java index 0f48aaecc5..0bb0d6d186 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/ContractUtils.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java @@ -10,45 +10,47 @@ * 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.tests.acceptance.dsl; +package tech.pegasys.pantheon.tests.acceptance.dsl.transaction; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; import java.io.IOException; import java.math.BigInteger; -import java.util.Arrays; import java.util.Collections; import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.TypeReference; import org.web3j.abi.datatypes.Function; -import org.web3j.abi.datatypes.Type; import org.web3j.crypto.Credentials; -import org.web3j.protocol.Web3j; -import org.web3j.protocol.Web3jService; -import org.web3j.protocol.core.JsonRpc2_0Web3j; import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.tx.RawTransactionManager; -@SuppressWarnings("rawtypes") -public class ContractUtils { +public class CallSmartContractFunctionWithRevert implements Transaction { private static final BigInteger GAS_PRICE = BigInteger.valueOf(1000); private static final BigInteger GAS_LIMIT = BigInteger.valueOf(3000000); private static final Credentials BENEFACTOR_ONE = Credentials.create(Accounts.GENESIS_ACCOUNT_ONE_PRIVATE_KEY); - public static EthSendTransaction sendWithRevert( - final String functionName, final String contractAddress, final Web3jService web3jService) - throws IOException { - final Function function = - new Function( - functionName, Arrays.asList(), Collections.>emptyList()); + private final String functionName; + private final String contractAddress; + + public CallSmartContractFunctionWithRevert( + final String functionName, final String contractAddress) { + this.functionName = functionName; + this.contractAddress = contractAddress; + } - final Web3j web3j = new JsonRpc2_0Web3j(web3jService); + @Override + public EthSendTransaction execute(final NodeRequests node) { + final Function function = + new Function(functionName, Collections.emptyList(), Collections.emptyList()); final RawTransactionManager transactionManager = - new RawTransactionManager(web3j, BENEFACTOR_ONE); - return transactionManager.sendTransaction( - GAS_PRICE, GAS_LIMIT, contractAddress, FunctionEncoder.encode(function), BigInteger.ZERO); + new RawTransactionManager(node.eth(), BENEFACTOR_ONE); + try { + return transactionManager.sendTransaction( + GAS_PRICE, GAS_LIMIT, contractAddress, FunctionEncoder.encode(function), BigInteger.ZERO); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/contract/ContractTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/contract/ContractTransactions.java index 3a917dc4b4..544cf5aa47 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/contract/ContractTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/contract/ContractTransactions.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.contract; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CallSmartContractFunctionWithRevert; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.DeploySmartContractTransaction; import org.web3j.tx.Contract; @@ -22,4 +23,9 @@ public DeploySmartContractTransaction createSmartContrac final Class clazz) { return new DeploySmartContractTransaction<>(clazz); } + + public CallSmartContractFunctionWithRevert callSmartContractWithRevert( + final String functionName, final String contractAddress) { + return new CallSmartContractFunctionWithRevert(functionName, contractAddress); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index cde329dd71..1258cf6778 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -12,8 +12,6 @@ */ package tech.pegasys.pantheon.tests.web3j; -import static tech.pegasys.pantheon.tests.acceptance.dsl.ContractUtils.sendWithRevert; - import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import tech.pegasys.pantheon.tests.web3j.generated.RevertReason; @@ -33,36 +31,30 @@ public void setUp() throws Exception { } @Test - public void mustRevertWithRevertReason() throws Exception { + public void mustRevertWithRevertReason() { final RevertReason revertReasonContract = minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); - - final EthSendTransaction ethSendTransaction = - sendWithRevert( - RevertReason.FUNC_REVERTWITHREVERTREASON, - revertReasonContract.getContractAddress(), - minerNode.web3jService()); - + final EthSendTransaction transaction = + minerNode.execute( + contractTransactions.callSmartContractWithRevert( + RevertReason.FUNC_REVERTWITHREVERTREASON, + revertReasonContract.getContractAddress())); minerNode.verify( eth.expectSuccessfulTransactionReceiptWithReason( - ethSendTransaction.getTransactionHash(), "RevertReason")); + transaction.getTransactionHash(), "RevertReason")); } @Test - public void mustRevertWithoutRevertReason() throws Exception { - + public void mustRevertWithoutRevertReason() { final RevertReason revertReasonContract = minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); - - final EthSendTransaction ethSendTransaction = - sendWithRevert( - RevertReason.FUNC_REVERTWITHOUTREVERTREASON, - revertReasonContract.getContractAddress(), - minerNode.web3jService()); - + final EthSendTransaction transaction = + minerNode.execute( + contractTransactions.callSmartContractWithRevert( + RevertReason.FUNC_REVERTWITHOUTREVERTREASON, + revertReasonContract.getContractAddress())); minerNode.verify( - eth.expectSuccessfulTransactionReceiptWithoutReason( - ethSendTransaction.getTransactionHash())); + eth.expectSuccessfulTransactionReceiptWithoutReason(transaction.getTransactionHash())); } } From 45cb0da47537cf3cfe07e9289f3d04c57fc68a50 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Mon, 1 Jul 2019 18:36:07 +1000 Subject: [PATCH 06/17] add final --- .../dsl/transaction/eth/EthRawRequestFactory.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java index 16338b621c..58061c177f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java @@ -12,7 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth; -import java.util.Arrays; +import java.util.Collections; import org.web3j.protocol.Web3jService; import org.web3j.protocol.core.Request; @@ -44,10 +44,10 @@ public EthRawRequestFactory(final Web3jService web3jService) { } public Request ethGetTransactionReceiptRaw( - String transactionHash) { + final String transactionHash) { return new Request<>( "eth_getTransactionReceipt", - Arrays.asList(transactionHash), + Collections.singletonList(transactionHash), web3jService, EthGetTransactionReceiptRawResponse.class); } From 5e00f0cf25605fafd7af192e118321289f0746cd Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 08:19:54 +1000 Subject: [PATCH 07/17] revert reason AT configuration --- .../tests/acceptance/dsl/node/PantheonNode.java | 8 ++++++++ .../dsl/node/ProcessPantheonNodeRunner.java | 4 ++++ .../dsl/node/ThreadPantheonNodeRunner.java | 5 +---- .../dsl/node/configuration/NodeConfiguration.java | 2 ++ .../configuration/PantheonFactoryConfiguration.java | 7 +++++++ .../PantheonFactoryConfigurationBuilder.java | 7 +++++++ .../dsl/node/configuration/PantheonNodeFactory.java | 12 ++++++++++++ .../privacy/PrivacyPantheonFactoryConfiguration.java | 2 ++ .../PrivacyPantheonFactoryConfigurationBuilder.java | 1 + .../privacy/PrivacyPantheonNodeFactory.java | 1 + .../tests/acceptance/dsl/privacy/PrivacyNode.java | 2 ++ .../tests/web3j/RevertReasonAcceptanceTest.java | 2 +- 12 files changed, 48 insertions(+), 5 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index f9eb735f18..8c2db94e3b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -79,6 +79,7 @@ public class PantheonNode implements NodeConfiguration, RunnableNode, AutoClosea private final KeyPair keyPair; private final Properties portsProperties = new Properties(); private final Boolean p2pEnabled; + private final boolean revertReasonEnabled; private final String name; private final MiningParameters miningParameters; @@ -115,10 +116,12 @@ public PantheonNode( final boolean p2pEnabled, final boolean discoveryEnabled, final boolean bootnodeEligible, + final boolean revertReasonEnabled, final List plugins, final List extraCLIOptions) throws IOException { this.bootnodeEligible = bootnodeEligible; + this.revertReasonEnabled = revertReasonEnabled; this.homeDirectory = Files.createTempDirectory("acctest"); keyfilePath.ifPresent( path -> { @@ -515,6 +518,11 @@ public List getExtraCLIOptions() { return extraCLIOptions; } + @Override + public boolean isRevertReasonEnabled() { + return revertReasonEnabled; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 081bc8cfc4..64c6173735 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -145,6 +145,10 @@ public void startNode(final PantheonNode node) { params.add("false"); } + if (node.isRevertReasonEnabled()) { + params.add("--revert-reason-enabled"); + } + node.getPermissioningConfiguration() .flatMap(PermissioningConfiguration::getLocalConfig) .ifPresent( diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index c7c967a73e..8481fe19f1 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -102,10 +102,6 @@ public void startNode(final PantheonNode node) { final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build(); final PantheonControllerBuilder builder = new PantheonController.Builder().fromEthNetworkConfig(ethNetworkConfig); - if (node.getName() - .contains("withRevertReason")) { // TODO: find better way to enable the revert reason - builder.isRevertReasonEnabled(true); - } final Path tempDir = Files.createTempDir().toPath(); final PantheonController pantheonController; @@ -122,6 +118,7 @@ public void startNode(final PantheonNode node) { .rocksDbConfiguration(new RocksDbConfiguration.Builder().databaseDir(tempDir).build()) .ethereumWireProtocolConfiguration(EthereumWireProtocolConfiguration.defaultConfig()) .clock(Clock.systemUTC()) + .isRevertReasonEnabled(node.isRevertReasonEnabled()) .build(); } catch (final IOException e) { throw new RuntimeException("Error building PantheonController", e); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java index 36621e2592..ce86b46886 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/NodeConfiguration.java @@ -47,4 +47,6 @@ public interface NodeConfiguration { boolean isBootnodeEligible(); List getExtraCLIOptions(); + + boolean isRevertReasonEnabled(); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfiguration.java index 1e486075fc..61c3af1c19 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfiguration.java @@ -38,6 +38,7 @@ public class PantheonFactoryConfiguration { private final boolean p2pEnabled; private final boolean discoveryEnabled; private final boolean bootnodeEligible; + private final boolean revertReasonEnabled; private final List plugins; private final List extraCLIOptions; @@ -55,6 +56,7 @@ public PantheonFactoryConfiguration( final boolean p2pEnabled, final boolean discoveryEnabled, final boolean bootnodeEligible, + final boolean revertReasonEnabled, final List plugins, final List extraCLIOptions) { this.name = name; @@ -70,6 +72,7 @@ public PantheonFactoryConfiguration( this.p2pEnabled = p2pEnabled; this.discoveryEnabled = discoveryEnabled; this.bootnodeEligible = bootnodeEligible; + this.revertReasonEnabled = revertReasonEnabled; this.plugins = plugins; this.extraCLIOptions = extraCLIOptions; } @@ -133,4 +136,8 @@ public List getPlugins() { public List getExtraCLIOptions() { return extraCLIOptions; } + + public boolean isRevertReasonEnabled() { + return revertReasonEnabled; + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java index a673c26b30..920058e208 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java @@ -47,6 +47,7 @@ public class PantheonFactoryConfigurationBuilder { private Boolean p2pEnabled = true; private boolean discoveryEnabled = true; private boolean bootnodeEligible = true; + private boolean revertReasonEnabled = false; private List plugins = new ArrayList<>(); private List extraCLIOptions = new ArrayList<>(); @@ -179,6 +180,11 @@ public PantheonFactoryConfigurationBuilder extraCLIOptions(final List ex return this; } + public PantheonFactoryConfigurationBuilder revertReasonEnabled() { + this.revertReasonEnabled = true; + return this; + } + public PantheonFactoryConfiguration build() { return new PantheonFactoryConfiguration( name, @@ -194,6 +200,7 @@ public PantheonFactoryConfiguration build() { p2pEnabled, discoveryEnabled, bootnodeEligible, + revertReasonEnabled, plugins, extraCLIOptions); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java index aded2d7499..2adf98d93a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java @@ -46,6 +46,7 @@ public PantheonNode create(final PantheonFactoryConfiguration config) throws IOE config.isP2pEnabled(), config.isDiscoveryEnabled(), config.isBootnodeEligible(), + config.isRevertReasonEnabled(), config.getPlugins(), config.getExtraCLIOptions()); } @@ -60,6 +61,17 @@ public PantheonNode createMinerNode(final String name) throws IOException { .build()); } + public PantheonNode createMinerNodeWithRevertReasonEnabled(final String name) throws IOException { + return create( + new PantheonFactoryConfigurationBuilder() + .name(name) + .miningEnabled() + .jsonRpcEnabled() + .webSocketEnabled() + .revertReasonEnabled() + .build()); + } + public PantheonNode createArchiveNode(final String name) throws IOException { return create( new PantheonFactoryConfigurationBuilder() diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfiguration.java index c379e963e9..85c50e84d8 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfiguration.java @@ -43,6 +43,7 @@ public class PrivacyPantheonFactoryConfiguration extends PantheonFactoryConfigur final boolean p2pEnabled, final boolean discoveryEnabled, final boolean bootnodeEligible, + final boolean revertReasonEnabled, final List plugins, final List extraCLIOptions, final OrionTestHarness orion) { @@ -60,6 +61,7 @@ public class PrivacyPantheonFactoryConfiguration extends PantheonFactoryConfigur p2pEnabled, discoveryEnabled, bootnodeEligible, + revertReasonEnabled, plugins, extraCLIOptions); this.orion = orion; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfigurationBuilder.java index 927062c3e6..447c4a0f04 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonFactoryConfigurationBuilder.java @@ -46,6 +46,7 @@ public PrivacyPantheonFactoryConfiguration build() { config.isP2pEnabled(), config.isDiscoveryEnabled(), config.isBootnodeEligible(), + config.isRevertReasonEnabled(), config.getPlugins(), config.getExtraCLIOptions(), orion); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonNodeFactory.java index b7f43f4479..f301938fba 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/privacy/PrivacyPantheonNodeFactory.java @@ -42,6 +42,7 @@ private static PrivacyNode create(final PrivacyPantheonFactoryConfiguration conf config.isP2pEnabled(), config.isDiscoveryEnabled(), config.isBootnodeEligible(), + config.isRevertReasonEnabled(), config.getPlugins(), config.getExtraCLIOptions(), config.getOrion()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivacyNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivacyNode.java index 10de64e65d..894ddbf473 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivacyNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivacyNode.java @@ -57,6 +57,7 @@ public PrivacyNode( final boolean p2pEnabled, final boolean discoveryEnabled, final boolean bootnodeEligible, + final boolean revertReasonEnabled, final List plugins, final List extraCLIOptions, final OrionTestHarness orion) @@ -75,6 +76,7 @@ public PrivacyNode( p2pEnabled, discoveryEnabled, bootnodeEligible, + revertReasonEnabled, plugins, extraCLIOptions); this.orion = orion; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index 1258cf6778..faf177ad1b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -26,7 +26,7 @@ public class RevertReasonAcceptanceTest extends AcceptanceTestBase { @Before public void setUp() throws Exception { - minerNode = pantheon.createMinerNode("miner-node-withRevertReason"); + minerNode = pantheon.createMinerNodeWithRevertReasonEnabled("miner-node-withRevertReason"); cluster.start(minerNode); } From fdef2bc4fd9423d28ed09e25fec0f6186af83231 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 10:25:20 +1000 Subject: [PATCH 08/17] rename transaction class --- ...ExpectSuccessfulEthGetTransactionReceiptWithReason.java | 7 +++---- ...ectSuccessfulEthGetTransactionReceiptWithoutReason.java | 6 +++--- ...seTransaction.java => EthGetTransactionReceiptRaw.java} | 5 ++--- .../acceptance/dsl/transaction/eth/EthTransactions.java | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/{EthGetTransactionReceiptRawResponseTransaction.java => EthGetTransactionReceiptRaw.java} (88%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java index 68a0ba1a1b..53fb01ca57 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -17,19 +17,18 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; import java.util.Optional; public class ExpectSuccessfulEthGetTransactionReceiptWithReason implements Condition { - private final EthGetTransactionReceiptRawResponseTransaction transaction; + private final EthGetTransactionReceiptRaw transaction; private final String expectedRevertReason; public ExpectSuccessfulEthGetTransactionReceiptWithReason( - final EthGetTransactionReceiptRawResponseTransaction transaction, - final String expectedRevertReason) { + final EthGetTransactionReceiptRaw transaction, final String expectedRevertReason) { this.transaction = transaction; this.expectedRevertReason = expectedRevertReason; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java index b00348a7ef..62d586cd36 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -17,17 +17,17 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRawResponseTransaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; import java.util.Optional; public class ExpectSuccessfulEthGetTransactionReceiptWithoutReason implements Condition { - private final EthGetTransactionReceiptRawResponseTransaction transaction; + private final EthGetTransactionReceiptRaw transaction; public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( - final EthGetTransactionReceiptRawResponseTransaction transaction) { + final EthGetTransactionReceiptRaw transaction) { this.transaction = transaction; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java similarity index 88% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java index 7e89651072..edbe322783 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRawResponseTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java @@ -22,11 +22,10 @@ import java.io.IOException; import java.util.Optional; -public class EthGetTransactionReceiptRawResponseTransaction - implements Transaction> { +public class EthGetTransactionReceiptRaw implements Transaction> { private final String transactionHash; - public EthGetTransactionReceiptRawResponseTransaction(final String transactionHash) { + public EthGetTransactionReceiptRaw(final String transactionHash) { this.transactionHash = transactionHash; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java index c54efd37d0..2e6167c7c0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java @@ -56,8 +56,8 @@ public EthGetTransactionCountTransaction getTransactionCount(final String accoun return new EthGetTransactionCountTransaction(accountAddress); } - public EthGetTransactionReceiptRawResponseTransaction getTransactionReceiptRawResponseTransaction( + public EthGetTransactionReceiptRaw getTransactionReceiptRawResponseTransaction( final String transactionHash) { - return new EthGetTransactionReceiptRawResponseTransaction(transactionHash); + return new EthGetTransactionReceiptRaw(transactionHash); } } From 96697bc74d64aa73c056ff8f1f7ff891c935191a Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 10:31:01 +1000 Subject: [PATCH 09/17] formatting --- .../pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index faf177ad1b..dd8f4ea38f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -32,7 +32,6 @@ public void setUp() throws Exception { @Test public void mustRevertWithRevertReason() { - final RevertReason revertReasonContract = minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); final EthSendTransaction transaction = From c1332637d22d4b6f70af649a622d28ccfd35e71b Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 10:40:06 +1000 Subject: [PATCH 10/17] add receipt with revert reason method to block data generator --- .../ethereum/core/BlockDataGenerator.java | 5 ++++ .../core/BlockDataGeneratorWithReason.java | 25 ------------------- .../ethereum/core/TransactionReceiptTest.java | 4 +-- 3 files changed, 7 insertions(+), 27 deletions(-) delete mode 100644 ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java index 43b7377d8c..3b46c2797b 100644 --- a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java +++ b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGenerator.java @@ -302,6 +302,11 @@ public TransactionReceipt receipt(final long cumulativeGasUsed) { hash(), cumulativeGasUsed, Arrays.asList(log(), log()), Optional.empty()); } + public TransactionReceipt receipt(final String revertReason) { + return new TransactionReceipt( + hash(), positiveLong(), Arrays.asList(log(), log()), Optional.of(revertReason)); + } + public TransactionReceipt receipt() { return receipt(positiveLong()); } diff --git a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java b/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java deleted file mode 100644 index fb4ebba8be..0000000000 --- a/ethereum/core/src/test-support/java/tech/pegasys/pantheon/ethereum/core/BlockDataGeneratorWithReason.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2019 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 java.util.Arrays; -import java.util.Optional; - -public class BlockDataGeneratorWithReason extends BlockDataGenerator { - - @Override - public TransactionReceipt receipt(final long cumulativeGasUsed) { - return new TransactionReceipt( - hash(), cumulativeGasUsed, Arrays.asList(log(), log()), Optional.of("Reason")); - } -} diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java index 09c6f28354..fb202cab87 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionReceiptTest.java @@ -31,8 +31,8 @@ public void toFromRlp() { @Test public void toFromRlpWithReason() { - final BlockDataGenerator gen = new BlockDataGeneratorWithReason(); - final TransactionReceipt receipt = gen.receipt(); + final BlockDataGenerator gen = new BlockDataGenerator(); + final TransactionReceipt receipt = gen.receipt("RevertReason"); final TransactionReceipt copy = TransactionReceipt.readFrom(RLP.input(RLP.encode(receipt::writeToWithRevertReason))); assertEquals(receipt, copy); From 91496e8b2e74c771303c095e2c7dd969777db74b Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 11:39:16 +1000 Subject: [PATCH 11/17] simplify revert reason solidity contract --- .../pantheon/tests/web3j/RevertReason.sol | 17 ++--------- .../tests/web3j/generated/RevertReason.abi | 2 +- .../tests/web3j/generated/RevertReason.bin | 2 +- .../tests/web3j/generated/RevertReason.java | 30 +++++-------------- 4 files changed, 13 insertions(+), 38 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol index cd3a07a97c..23d7cdfc75 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol @@ -18,22 +18,11 @@ pragma solidity >=0.4.0 <0.6.0; // web3j solidity generate -b ./generated/RevertReason.bin -a ./generated/RevertReason.abi -o ../../../../../ -p tech.pegasys.pantheon.tests.web3j.generated contract RevertReason { - uint public value = 0; - - function revertWithRevertReason() public { - if (true) { - revert("RevertReason"); - } else { - value = value + 1; - } + function revertWithRevertReason() public pure returns (bool) { + revert("RevertReason"); } - function revertWithoutRevertReason() public { - if (true) { - revert(); - } else { - value = value + 1; - } + function revertWithoutRevertReason() public pure returns (bool) { revert(); } } \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi index 90d71569e0..e1bf8b0463 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.abi @@ -1 +1 @@ -[{"constant":false,"inputs":[],"name":"revertWithRevertReason","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"revertWithoutRevertReason","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"constant":true,"inputs":[],"name":"revertWithRevertReason","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"revertWithoutRevertReason","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"}] \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin index 67ba788b46..1848ca10c1 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.bin @@ -1 +1 @@ -60806040526000805534801561001457600080fd5b5060de806100236000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806311f95f6f1460415780633fa4f245146049578063ff489d31146061575b600080fd5b60476067565b005b604f60a3565b60408051918252519081900360200190f35b6047603c565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b604482015290519081900360640190fd5b6000548156fea265627a7a72305820344bbe39744359c54d48fe55c3f74fd985bb207dd59e3b0e041c55ce0ec876cb64736f6c63430005090032 \ No newline at end of file +608060405234801561001057600080fd5b5060d18061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806311f95f6f146037578063ff489d31146051575b600080fd5b603d6057565b604080519115158252519081900360200190f35b603d6095565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b6044820152905160009181900360640190fd5b6000806000fdfea265627a7a723058202dd24b599e57aa54899e1beceec3fb4a5001fccb4be994e8d18aa03cc123708764736f6c634300050a0032 \ No newline at end of file diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java index c0e0bc61f8..048cb18373 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java @@ -14,16 +14,14 @@ import java.math.BigInteger; import java.util.Arrays; -import java.util.Collections; import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Bool; import org.web3j.abi.datatypes.Function; import org.web3j.abi.datatypes.Type; -import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.crypto.Credentials; import org.web3j.protocol.Web3j; import org.web3j.protocol.core.RemoteCall; -import org.web3j.protocol.core.methods.response.TransactionReceipt; import org.web3j.tx.Contract; import org.web3j.tx.TransactionManager; import org.web3j.tx.gas.ContractGasProvider; @@ -39,15 +37,12 @@ * *

Generated with web3j version 4.3.0. */ -@SuppressWarnings("rawtypes") public class RevertReason extends Contract { private static final String BINARY = - "60806040526000805534801561001457600080fd5b5060de806100236000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c806311f95f6f1460415780633fa4f245146049578063ff489d31146061575b600080fd5b60476067565b005b604f60a3565b60408051918252519081900360200190f35b6047603c565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b604482015290519081900360640190fd5b6000548156fea265627a7a72305820344bbe39744359c54d48fe55c3f74fd985bb207dd59e3b0e041c55ce0ec876cb64736f6c63430005090032"; + "608060405234801561001057600080fd5b5060d18061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806311f95f6f146037578063ff489d31146051575b600080fd5b603d6057565b604080519115158252519081900360200190f35b603d6095565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b6044820152905160009181900360640190fd5b6000806000fdfea265627a7a723058202dd24b599e57aa54899e1beceec3fb4a5001fccb4be994e8d18aa03cc123708764736f6c634300050a0032"; public static final String FUNC_REVERTWITHREVERTREASON = "revertWithRevertReason"; - public static final String FUNC_VALUE = "value"; - public static final String FUNC_REVERTWITHOUTREVERTREASON = "revertWithoutRevertReason"; @Deprecated @@ -86,31 +81,22 @@ protected RevertReason( super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider); } - public RemoteCall revertWithRevertReason() { + public RemoteCall revertWithRevertReason() { final Function function = new Function( FUNC_REVERTWITHREVERTREASON, Arrays.asList(), - Collections.>emptyList()); - return executeRemoteCallTransaction(function); - } - - public RemoteCall value() { - final Function function = - new Function( - FUNC_VALUE, - Arrays.asList(), - Arrays.>asList(new TypeReference() {})); - return executeRemoteCallSingleValueReturn(function, BigInteger.class); + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, Boolean.class); } - public RemoteCall revertWithoutRevertReason() { + public RemoteCall revertWithoutRevertReason() { final Function function = new Function( FUNC_REVERTWITHOUTREVERTREASON, Arrays.asList(), - Collections.>emptyList()); - return executeRemoteCallTransaction(function); + Arrays.>asList(new TypeReference() {})); + return executeRemoteCallSingleValueReturn(function, Boolean.class); } @Deprecated From 267700b63bdd5ceb254ec89b01f83d8bea8bed00 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Tue, 2 Jul 2019 12:41:38 +1000 Subject: [PATCH 12/17] ignore raw types for generated code --- .../pegasys/pantheon/tests/web3j/generated/RevertReason.java | 1 + 1 file changed, 1 insertion(+) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java index 048cb18373..965bf43aec 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/generated/RevertReason.java @@ -37,6 +37,7 @@ * *

Generated with web3j version 4.3.0. */ +@SuppressWarnings("rawtypes") public class RevertReason extends Contract { private static final String BINARY = "608060405234801561001057600080fd5b5060d18061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806311f95f6f146037578063ff489d31146051575b600080fd5b603d6057565b604080519115158252519081900360200190f35b603d6095565b6040805162461bcd60e51b815260206004820152600c60248201526b2932bb32b93a2932b0b9b7b760a11b6044820152905160009181900360640190fd5b6000806000fdfea265627a7a723058202dd24b599e57aa54899e1beceec3fb4a5001fccb4be994e8d18aa03cc123708764736f6c634300050a0032"; From 206cc007f1453d29cb9a85f01d40eb1225384764 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Wed, 3 Jul 2019 08:39:56 +1000 Subject: [PATCH 13/17] PR changes --- ...cessfulEthGetTransactionReceiptWithReason.java | 14 +++++--------- ...sfulEthGetTransactionReceiptWithoutReason.java | 11 +++++------ ...Revert.java => CallSmartContractFunction.java} | 5 ++--- .../contract/ContractTransactions.java | 6 +++--- .../eth/EthGetTransactionReceiptRaw.java | 2 +- .../pegasys/pantheon/tests/web3j/RevertReason.sol | 2 +- .../tests/web3j/RevertReasonAcceptanceTest.java | 15 ++++++++------- .../src/test/resources/everything_config.toml | 2 +- 8 files changed, 26 insertions(+), 31 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/{CallSmartContractFunctionWithRevert.java => CallSmartContractFunction.java} (90%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java index 53fb01ca57..fd643101bf 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 ConsenSys AG. + * Copyright 2019 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 @@ -18,9 +18,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; - -import java.util.Optional; public class ExpectSuccessfulEthGetTransactionReceiptWithReason implements Condition { @@ -35,15 +32,14 @@ public ExpectSuccessfulEthGetTransactionReceiptWithReason( @Override public void verify(final Node node) { - WaitUtils.waitFor( - () -> assertThat(revertReasonMatches(node, expectedRevertReason)).isPresent()); + WaitUtils.waitFor(() -> assertThat(revertReasonMatches(node, expectedRevertReason))); } - private Optional revertReasonMatches( - final Node node, final String expectedRevertReason) { + private boolean revertReasonMatches(final Node node, final String expectedRevertReason) { return node.execute(transaction) .filter( transactionReceipt -> - transactionReceipt.getRevertReason().contains(expectedRevertReason)); + transactionReceipt.getRevertReason().contains(expectedRevertReason)) + .isPresent(); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java index 62d586cd36..bb61a37ae9 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 ConsenSys AG. + * Copyright 2019 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 @@ -20,8 +20,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; -import java.util.Optional; - public class ExpectSuccessfulEthGetTransactionReceiptWithoutReason implements Condition { private final EthGetTransactionReceiptRaw transaction; @@ -33,12 +31,13 @@ public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(revertReasonIsEmpty(node)).isPresent()); + WaitUtils.waitFor(() -> assertThat(revertReasonIsEmpty(node))); } - private Optional revertReasonIsEmpty(final Node node) { + private boolean revertReasonIsEmpty(final Node node) { return node.execute(transaction) .map(TransactionReceiptRaw::getRevertReason) - .filter(String::isEmpty); + .filter(String::isEmpty) + .isPresent(); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunction.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunction.java index 0bb0d6d186..ea692bfc0d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunctionWithRevert.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CallSmartContractFunction.java @@ -24,7 +24,7 @@ import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.tx.RawTransactionManager; -public class CallSmartContractFunctionWithRevert implements Transaction { +public class CallSmartContractFunction implements Transaction { private static final BigInteger GAS_PRICE = BigInteger.valueOf(1000); private static final BigInteger GAS_LIMIT = BigInteger.valueOf(3000000); @@ -34,8 +34,7 @@ public class CallSmartContractFunctionWithRevert implements Transaction DeploySmartContractTransaction createSmartContrac return new DeploySmartContractTransaction<>(clazz); } - public CallSmartContractFunctionWithRevert callSmartContractWithRevert( + public CallSmartContractFunction callSmartContract( final String functionName, final String contractAddress) { - return new CallSmartContractFunctionWithRevert(functionName, contractAddress); + return new CallSmartContractFunction(functionName, contractAddress); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java index edbe322783..75a86ea611 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 ConsenSys AG. + * Copyright 2019 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 diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol index 23d7cdfc75..e4c6247379 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReason.sol @@ -1,5 +1,5 @@ /* - * Copyright 2018 ConsenSys AG. + * Copyright 2019 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 diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java index dd8f4ea38f..c50ea845f8 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/RevertReasonAcceptanceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 ConsenSys AG. + * Copyright 2019 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 @@ -12,6 +12,9 @@ */ package tech.pegasys.pantheon.tests.web3j; +import static tech.pegasys.pantheon.tests.web3j.generated.RevertReason.FUNC_REVERTWITHOUTREVERTREASON; +import static tech.pegasys.pantheon.tests.web3j.generated.RevertReason.FUNC_REVERTWITHREVERTREASON; + import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import tech.pegasys.pantheon.tests.web3j.generated.RevertReason; @@ -36,9 +39,8 @@ public void mustRevertWithRevertReason() { minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); final EthSendTransaction transaction = minerNode.execute( - contractTransactions.callSmartContractWithRevert( - RevertReason.FUNC_REVERTWITHREVERTREASON, - revertReasonContract.getContractAddress())); + contractTransactions.callSmartContract( + FUNC_REVERTWITHREVERTREASON, revertReasonContract.getContractAddress())); minerNode.verify( eth.expectSuccessfulTransactionReceiptWithReason( transaction.getTransactionHash(), "RevertReason")); @@ -50,9 +52,8 @@ public void mustRevertWithoutRevertReason() { minerNode.execute(contractTransactions.createSmartContract(RevertReason.class)); final EthSendTransaction transaction = minerNode.execute( - contractTransactions.callSmartContractWithRevert( - RevertReason.FUNC_REVERTWITHOUTREVERTREASON, - revertReasonContract.getContractAddress())); + contractTransactions.callSmartContract( + FUNC_REVERTWITHOUTREVERTREASON, revertReasonContract.getContractAddress())); minerNode.verify( eth.expectSuccessfulTransactionReceiptWithoutReason(transaction.getTransactionHash())); } diff --git a/pantheon/src/test/resources/everything_config.toml b/pantheon/src/test/resources/everything_config.toml index c539c0e5d9..c8ea03d2c8 100644 --- a/pantheon/src/test/resources/everything_config.toml +++ b/pantheon/src/test/resources/everything_config.toml @@ -99,5 +99,5 @@ tx-pool-retention-hours=999 tx-pool-max-size=1234 Xincoming-tx-messages-keep-alive-seconds=60 -# Revert Reaspm +# Revert Reason revert-reason-enabled=false \ No newline at end of file From b0fb5095d6a0fdd94cf6ad906e03c77371582b2e Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Wed, 3 Jul 2019 08:48:28 +1000 Subject: [PATCH 14/17] PR changes --- .../eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java | 2 +- .../ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java index fd643101bf..0c68b7023c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -32,7 +32,7 @@ public ExpectSuccessfulEthGetTransactionReceiptWithReason( @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(revertReasonMatches(node, expectedRevertReason))); + WaitUtils.waitFor(() -> assertThat(revertReasonMatches(node, expectedRevertReason)).isTrue()); } private boolean revertReasonMatches(final Node node, final String expectedRevertReason) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java index bb61a37ae9..d85753e0b0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -31,7 +31,7 @@ public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(revertReasonIsEmpty(node))); + WaitUtils.waitFor(() -> assertThat(revertReasonIsEmpty(node)).isTrue()); } private boolean revertReasonIsEmpty(final Node node) { From 26af22b75605bbd3b8b6f4f8d6e3fe926f01c7bd Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Wed, 3 Jul 2019 10:25:33 +1000 Subject: [PATCH 15/17] PR changes --- .../dsl/condition/eth/EthConditions.java | 6 ++-- ...fulEthGetTransactionReceiptWithReason.java | 7 ++-- ...EthGetTransactionReceiptWithoutReason.java | 10 +++--- .../acceptance/dsl/node/PantheonNode.java | 6 ++-- .../dsl/transaction/NodeRequests.java | 30 ++++++---------- ...etTransactionReceiptWithRevertReason.java} | 15 ++++---- .../dsl/transaction/eth/EthTransactions.java | 7 ++-- .../net/CustomNetJsonRpcRequestFactory.java | 36 ------------------- .../CustomRequestFactory.java} | 30 ++++++++++------ .../net/NetServicesTransaction.java | 7 ++-- 10 files changed, 58 insertions(+), 96 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/{EthGetTransactionReceiptRaw.java => EthGetTransactionReceiptWithRevertReason.java} (62%) delete mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomNetJsonRpcRequestFactory.java rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/{eth/EthRawRequestFactory.java => net/CustomRequestFactory.java} (57%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java index e68ff180ce..982ca4145b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java @@ -48,17 +48,17 @@ public Condition expectNoTransactionReceipt(final String transactionHash) { public Condition sendRawTransactionExceptional( final String transactionData, final String expectedMessage) { return new ExpectEthSendRawTransactionException( - transactions.sendRawTransactionTransaction(transactionData), expectedMessage); + transactions.sendRawTransaction(transactionData), expectedMessage); } public Condition expectSuccessfulTransactionReceiptWithReason( final String transactionHash, final String revertReason) { return new ExpectSuccessfulEthGetTransactionReceiptWithReason( - transactions.getTransactionReceiptRawResponseTransaction(transactionHash), revertReason); + transactions.getTransactionReceiptWithRevertReason(transactionHash), revertReason); } public Condition expectSuccessfulTransactionReceiptWithoutReason(final String transactionHash) { return new ExpectSuccessfulEthGetTransactionReceiptWithoutReason( - transactions.getTransactionReceiptRawResponseTransaction(transactionHash)); + transactions.getTransactionReceiptWithRevertReason(transactionHash)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java index 0c68b7023c..8dffef90b0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithReason.java @@ -17,15 +17,16 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptWithRevertReason; public class ExpectSuccessfulEthGetTransactionReceiptWithReason implements Condition { - private final EthGetTransactionReceiptRaw transaction; + private final EthGetTransactionReceiptWithRevertReason transaction; private final String expectedRevertReason; public ExpectSuccessfulEthGetTransactionReceiptWithReason( - final EthGetTransactionReceiptRaw transaction, final String expectedRevertReason) { + final EthGetTransactionReceiptWithRevertReason transaction, + final String expectedRevertReason) { this.transaction = transaction; this.expectedRevertReason = expectedRevertReason; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java index d85753e0b0..75a45ee0ce 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/ExpectSuccessfulEthGetTransactionReceiptWithoutReason.java @@ -17,15 +17,15 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptRaw; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthGetTransactionReceiptWithRevertReason; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory.TransactionReceiptWithRevertReason; public class ExpectSuccessfulEthGetTransactionReceiptWithoutReason implements Condition { - private final EthGetTransactionReceiptRaw transaction; + private final EthGetTransactionReceiptWithRevertReason transaction; public ExpectSuccessfulEthGetTransactionReceiptWithoutReason( - final EthGetTransactionReceiptRaw transaction) { + final EthGetTransactionReceiptWithRevertReason transaction) { this.transaction = transaction; } @@ -36,7 +36,7 @@ public void verify(final Node node) { private boolean revertReasonIsEmpty(final Node node) { return node.execute(transaction) - .map(TransactionReceiptRaw::getRevertReason) + .map(TransactionReceiptWithRevertReason::getRevertReason) .filter(String::isEmpty) .isPresent(); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index 8c2db94e3b..487bd24212 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -34,10 +34,9 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.admin.AdminRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomNetJsonRpcRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; import java.io.File; @@ -282,13 +281,12 @@ private NodeRequests nodeRequests() { nodeRequests = new NodeRequests( new JsonRpc2_0Web3j(web3jService, 2000, Async.defaultExecutorService()), - new EthRawRequestFactory(web3jService), new CliqueRequestFactory(web3jService), new Ibft2RequestFactory(web3jService), new PermissioningJsonRpcRequestFactory(web3jService), new AdminRequestFactory(web3jService), new EeaRequestFactory(web3jService), - new CustomNetJsonRpcRequestFactory(web3jService), + new CustomRequestFactory(web3jService), websocketService, loginRequestFactory()); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java index b517c89c50..247859588a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java @@ -15,62 +15,54 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.admin.AdminRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomNetJsonRpcRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; import java.util.Optional; -import org.web3j.protocol.core.JsonRpc2_0Web3j; +import org.web3j.protocol.Web3j; import org.web3j.protocol.websocket.WebSocketService; public class NodeRequests { - private final JsonRpc2_0Web3j netEth; - private final EthRawRequestFactory ethRaw; + private final Web3j netEth; private final CliqueRequestFactory clique; private final Ibft2RequestFactory ibft; private final PermissioningJsonRpcRequestFactory perm; private final AdminRequestFactory admin; private final EeaRequestFactory eea; - private final CustomNetJsonRpcRequestFactory customNet; + private final CustomRequestFactory custom; private final Optional websocketService; private final LoginRequestFactory login; public NodeRequests( - final JsonRpc2_0Web3j netEth, - final EthRawRequestFactory ethRaw, + final Web3j netEth, final CliqueRequestFactory clique, final Ibft2RequestFactory ibft, final PermissioningJsonRpcRequestFactory perm, final AdminRequestFactory admin, final EeaRequestFactory eea, - final CustomNetJsonRpcRequestFactory customNet, + final CustomRequestFactory custom, final Optional websocketService, final LoginRequestFactory login) { this.netEth = netEth; - this.ethRaw = ethRaw; this.clique = clique; this.ibft = ibft; this.perm = perm; this.admin = admin; this.eea = eea; - this.customNet = customNet; + this.custom = custom; this.websocketService = websocketService; this.login = login; } - public JsonRpc2_0Web3j eth() { + public Web3j eth() { return netEth; } - public EthRawRequestFactory ethRaw() { - return ethRaw; - } - - public JsonRpc2_0Web3j net() { + public Web3j net() { return netEth; } @@ -90,8 +82,8 @@ public AdminRequestFactory admin() { return admin; } - public CustomNetJsonRpcRequestFactory customNet() { - return customNet; + public CustomRequestFactory custom() { + return custom; } public EeaRequestFactory eea() { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptWithRevertReason.java similarity index 62% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptWithRevertReason.java index 75a86ea611..748ae145ee 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptRaw.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptWithRevertReason.java @@ -16,24 +16,25 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.EthGetTransactionReceiptRawResponse; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthRawRequestFactory.TransactionReceiptRaw; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory.EthGetTransactionReceiptWithRevertReasonResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory.TransactionReceiptWithRevertReason; import java.io.IOException; import java.util.Optional; -public class EthGetTransactionReceiptRaw implements Transaction> { +public class EthGetTransactionReceiptWithRevertReason + implements Transaction> { private final String transactionHash; - public EthGetTransactionReceiptRaw(final String transactionHash) { + public EthGetTransactionReceiptWithRevertReason(final String transactionHash) { this.transactionHash = transactionHash; } @Override - public Optional execute(final NodeRequests node) { + public Optional execute(final NodeRequests node) { try { - final EthGetTransactionReceiptRawResponse response = - node.ethRaw().ethGetTransactionReceiptRaw(transactionHash).send(); + final EthGetTransactionReceiptWithRevertReasonResponse response = + node.custom().ethGetTransactionReceiptWithRevertReason(transactionHash).send(); assertThat(response.hasError()).isFalse(); return Optional.ofNullable(response.getResult()); } catch (final IOException e) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java index 2e6167c7c0..807b2f132f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java @@ -47,8 +47,7 @@ public EthGetTransactionReceiptTransaction getTransactionReceipt(final String tr return new EthGetTransactionReceiptTransaction(transactionHash); } - public EthSendRawTransactionTransaction sendRawTransactionTransaction( - final String transactionData) { + public EthSendRawTransactionTransaction sendRawTransaction(final String transactionData) { return new EthSendRawTransactionTransaction(transactionData); } @@ -56,8 +55,8 @@ public EthGetTransactionCountTransaction getTransactionCount(final String accoun return new EthGetTransactionCountTransaction(accountAddress); } - public EthGetTransactionReceiptRaw getTransactionReceiptRawResponseTransaction( + public EthGetTransactionReceiptWithRevertReason getTransactionReceiptWithRevertReason( final String transactionHash) { - return new EthGetTransactionReceiptRaw(transactionHash); + return new EthGetTransactionReceiptWithRevertReason(transactionHash); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomNetJsonRpcRequestFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomNetJsonRpcRequestFactory.java deleted file mode 100644 index bfd9e5a96f..0000000000 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomNetJsonRpcRequestFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2019 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.tests.acceptance.dsl.transaction.net; - -import java.util.Collections; -import java.util.Map; - -import org.web3j.protocol.Web3jService; -import org.web3j.protocol.core.Request; -import org.web3j.protocol.core.Response; - -public class CustomNetJsonRpcRequestFactory { - - public static class NetServicesResponse extends Response>> {} - - private final Web3jService web3jService; - - public CustomNetJsonRpcRequestFactory(final Web3jService web3jService) { - this.web3jService = web3jService; - } - - public Request netServices() { - return new Request<>( - "net_services", Collections.emptyList(), web3jService, NetServicesResponse.class); - } -} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomRequestFactory.java similarity index 57% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomRequestFactory.java index 58061c177f..8cb5ed9055 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthRawRequestFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/CustomRequestFactory.java @@ -10,21 +10,25 @@ * 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.tests.acceptance.dsl.transaction.eth; +package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net; import java.util.Collections; +import java.util.Map; import org.web3j.protocol.Web3jService; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.Response; import org.web3j.protocol.core.methods.response.TransactionReceipt; -public class EthRawRequestFactory { +public class CustomRequestFactory { + private final Web3jService web3jService; + + public static class NetServicesResponse extends Response>> {} - public static class TransactionReceiptRaw extends TransactionReceipt { + public static class TransactionReceiptWithRevertReason extends TransactionReceipt { private String revertReason; - public TransactionReceiptRaw() {} + public TransactionReceiptWithRevertReason() {} public void setRevertReason(final String revertReason) { this.revertReason = revertReason; @@ -35,20 +39,24 @@ public String getRevertReason() { } } - public static class EthGetTransactionReceiptRawResponse extends Response {} - - private final Web3jService web3jService; + public static class EthGetTransactionReceiptWithRevertReasonResponse + extends Response {} - public EthRawRequestFactory(final Web3jService web3jService) { + public CustomRequestFactory(final Web3jService web3jService) { this.web3jService = web3jService; } - public Request ethGetTransactionReceiptRaw( - final String transactionHash) { + public Request netServices() { + return new Request<>( + "net_services", Collections.emptyList(), web3jService, NetServicesResponse.class); + } + + public Request + ethGetTransactionReceiptWithRevertReason(final String transactionHash) { return new Request<>( "eth_getTransactionReceipt", Collections.singletonList(transactionHash), web3jService, - EthGetTransactionReceiptRawResponse.class); + EthGetTransactionReceiptWithRevertReasonResponse.class); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetServicesTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetServicesTransaction.java index bfd6ac0833..1503aa3772 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetServicesTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetServicesTransaction.java @@ -25,11 +25,10 @@ public class NetServicesTransaction implements Transaction> execute(final NodeRequests requestFactories) { - CustomNetJsonRpcRequestFactory.NetServicesResponse netServicesResponse = null; + CustomRequestFactory.NetServicesResponse netServicesResponse = null; try { - final CustomNetJsonRpcRequestFactory netServicesJsonRpcRequestFactory = - requestFactories.customNet(); - final Request request = + final CustomRequestFactory netServicesJsonRpcRequestFactory = requestFactories.custom(); + final Request request = netServicesJsonRpcRequestFactory.netServices(); netServicesResponse = request.send(); From 1a27344714cc42a8fdf54db8aa674f02efd5e444 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Wed, 3 Jul 2019 13:31:15 +1000 Subject: [PATCH 16/17] PR changes --- .../pegasys/pantheon/ethereum/core/TransactionReceipt.java | 4 ++-- .../pantheon/ethereum/mainnet/TransactionProcessor.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java index 8a9deee2e1..92f7b318a3 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java @@ -54,7 +54,7 @@ public class TransactionReceipt { * @param stateRoot the state root for the world state after the transaction has been processed * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction - * @param revertReason whether storing the revert reason is for failed transactions + * @param revertReason the revert reason for a failed transaction (if applicable) */ public TransactionReceipt( final Hash stateRoot, @@ -85,7 +85,7 @@ private TransactionReceipt( * @param status the status code for the transaction (1 for success and 0 for failure) * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction - * @param revertReason the revert reason + * @param revertReason the revert reason for a failed transaction */ public TransactionReceipt( final int status, diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java index b779f4d076..7d2931b48b 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/TransactionProcessor.java @@ -99,7 +99,7 @@ default boolean isSuccessful() { ValidationResult getValidationResult(); /** - * Returns the reason a transaction was reverted (if applicable). + * Returns the reason why a transaction was reverted (if applicable). * * @return the revert reason. */ From 471dc95631df29d197859fd0e0ed7c178f5524e6 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Wed, 3 Jul 2019 15:41:09 +1000 Subject: [PATCH 17/17] PR changes --- .../tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java index 92f7b318a3..a72c15eaa8 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/TransactionReceipt.java @@ -85,7 +85,7 @@ private TransactionReceipt( * @param status the status code for the transaction (1 for success and 0 for failure) * @param cumulativeGasUsed the total amount of gas consumed in the block after this transaction * @param logs the logs generated within the transaction - * @param revertReason the revert reason for a failed transaction + * @param revertReason the revert reason for a failed transaction (if applicable) */ public TransactionReceipt( final int status,