Skip to content

Commit

Permalink
Added validation for GoQuorum transactions with value. (hyperledger#2400
Browse files Browse the repository at this point in the history
)

* Added validation for GoQuorum transactions with value.

Signed-off-by: Mark Terry <mark.terry@consensys.net>
  • Loading branch information
mark-terry authored Jun 10, 2021
1 parent 7a125b3 commit 974f588
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public static JsonRpcError convertTransactionInvalidReason(
return JsonRpcError.ETH_SEND_TX_REPLACEMENT_UNDERPRICED;
case GAS_PRICE_MUST_BE_ZERO:
return JsonRpcError.GAS_PRICE_MUST_BE_ZERO;
case ETHER_VALUE_NOT_SUPPORTED:
return JsonRpcError.ETHER_VALUE_NOT_SUPPORTED;
default:
return JsonRpcError.INVALID_PARAMS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public enum JsonRpcError {
CREATE_PRIVACY_GROUP_ERROR(-50100, "Error creating privacy group"),
DECODE_ERROR(-50100, "Unable to decode the private signed raw transaction"),
DELETE_PRIVACY_GROUP_ERROR(-50100, "Error deleting privacy group"),
ETHER_VALUE_NOT_SUPPORTED(-50100, "ether value is not supported for private transactions"),
FIND_PRIVACY_GROUP_ERROR(-50100, "Error finding privacy group"),
FIND_ONCHAIN_PRIVACY_GROUP_ERROR(-50100, "Error finding onchain privacy group"),
GOQUORUM_NO_PRIVATE_FOR(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ public enum TransactionInvalidReason {
PRIVATE_UNIMPLEMENTED_TRANSACTION_TYPE,
INTERNAL_ERROR,
// Quroum Compatibility Invalid Reasons
GAS_PRICE_MUST_BE_ZERO
GAS_PRICE_MUST_BE_ZERO,
ETHER_VALUE_NOT_SUPPORTED
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.eth.transactions;

import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.apache.logging.log4j.LogManager.getLogger;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE;

Expand Down Expand Up @@ -46,6 +47,7 @@
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;

import java.math.BigInteger;
import java.util.Collection;
import java.util.HashSet;
import java.util.Optional;
Expand Down Expand Up @@ -232,6 +234,15 @@ public PendingTransactions getPendingTransactions() {
private ValidationResult<TransactionInvalidReason> validateTransaction(
final Transaction transaction) {
final BlockHeader chainHeadBlockHeader = getChainHeadBlockHeader();

// Check whether it's a GoQuorum transaction
if (isGoQuorumPrivateTransaction(transaction)) {
final Optional<Wei> weiValue = ofNullable(transaction.getValue());
if (weiValue.isPresent() && !weiValue.get().isZero()) {
return ValidationResult.invalid(TransactionInvalidReason.ETHER_VALUE_NOT_SUPPORTED);
}
}

final ValidationResult<TransactionInvalidReason> basicValidationResult =
getTransactionValidator().validate(transaction, Optional.empty());
if (!basicValidationResult.isValid()) {
Expand All @@ -251,7 +262,7 @@ private ValidationResult<TransactionInvalidReason> validateTransaction(
.orElse(false)) {
return ValidationResult.invalid(
TransactionInvalidReason.INVALID_TRANSACTION_FORMAT,
String.format("EIP-1559 transaction are not allowed yet"));
"EIP-1559 transaction are not allowed yet");
}

return protocolContext
Expand All @@ -276,6 +287,11 @@ private BlockHeader getChainHeadBlockHeader() {
return blockchain.getBlockHeader(blockchain.getChainHeadHash()).get();
}

private boolean isGoQuorumPrivateTransaction(final Transaction transaction) {
return (transaction.getV().equals(BigInteger.valueOf(37))
|| (transaction.getV().equals(BigInteger.valueOf(38))));
}

public interface TransactionBatchAddedListener {

void onTransactionsAdded(Iterable<Transaction> transactions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.testutil.TestClock;

import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -831,6 +832,45 @@ public void shouldRejectLocalTransactionIfFeeCapExceeded() {
assertThat(result.getInvalidReason()).isEqualTo(TransactionInvalidReason.TX_FEECAP_EXCEEDED);
}

@Test
public void shouldRejectGoQuorumTransactionWithNonZeroValue() {
final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create();
final EthContext ethContext = ethProtocolManager.ethContext();
final PeerTransactionTracker peerTransactionTracker = new PeerTransactionTracker();
final Wei twoEthers = Wei.fromEth(2);

final TransactionPool transactionPool =
new TransactionPool(
transactions,
protocolSchedule,
protocolContext,
batchAddedListener,
pendingBatchAddedListener,
syncState,
ethContext,
peerTransactionTracker,
peerPendingTransactionTracker,
Wei.ZERO,
metricsSystem,
Optional.empty(),
ImmutableTransactionPoolConfiguration.builder().txFeeCap(twoEthers).build());

final Transaction transaction37 =
Transaction.builder().v(BigInteger.valueOf(37)).value(Wei.ONE).build();
final Transaction transaction38 =
Transaction.builder().v(BigInteger.valueOf(38)).value(Wei.ONE).build();

final ValidationResult<TransactionInvalidReason> result37 =
transactionPool.addLocalTransaction(transaction37);
final ValidationResult<TransactionInvalidReason> result38 =
transactionPool.addLocalTransaction(transaction38);

assertThat(result37.getInvalidReason())
.isEqualTo(TransactionInvalidReason.ETHER_VALUE_NOT_SUPPORTED);
assertThat(result38.getInvalidReason())
.isEqualTo(TransactionInvalidReason.ETHER_VALUE_NOT_SUPPORTED);
}

private void assertTransactionPending(final Transaction t) {
assertThat(transactions.getTransactionByHash(t.getHash())).contains(t);
}
Expand Down

0 comments on commit 974f588

Please sign in to comment.