Allow future nonces for private transactions when validating before d… (#557)

* Allow future nonces for private transactions when validating before distribution

Signed-off-by: Stefan Pingel <stefan.pingel@consensys.net>
pull/563/head
Stefan Pingel 5 years ago committed by GitHub
parent c1b1460824
commit 0116d5f3bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/DefaultPrivacyController.java
  2. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionProcessor.java
  3. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionValidator.java
  4. 7
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/DefaultPrivacyControllerTest.java
  5. 59
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/PrivateTransactionValidatorTest.java

@ -170,7 +170,8 @@ public class DefaultPrivacyController implements PrivacyController {
final String privacyGroupId = privateTransaction.determinePrivacyGroupId();
return privateTransactionValidator.validate(
privateTransaction,
determineBesuNonce(privateTransaction.getSender(), privacyGroupId, enclavePublicKey));
determineBesuNonce(privateTransaction.getSender(), privacyGroupId, enclavePublicKey),
true);
}
@Override

@ -196,7 +196,7 @@ public class PrivateTransactionProcessor {
: privateWorldState.createAccount(senderAddress, 0, Wei.ZERO).getMutable();
final ValidationResult<TransactionValidator.TransactionInvalidReason> validationResult =
privateTransactionValidator.validate(transaction, sender.getNonce());
privateTransactionValidator.validate(transaction, sender.getNonce(), false);
if (!validationResult.isValid()) {
return Result.invalid(validationResult);
}

@ -35,7 +35,9 @@ public class PrivateTransactionValidator {
}
public ValidationResult<TransactionValidator.TransactionInvalidReason> validate(
final PrivateTransaction transaction, final Long accountNonce) {
final PrivateTransaction transaction,
final Long accountNonce,
final boolean allowFutureNonces) {
LOG.debug("Validating private transaction fields of {}", transaction.getHash());
final ValidationResult<TransactionInvalidReason> privateFieldsValidationResult =
validatePrivateTransactionFields(transaction);
@ -74,7 +76,7 @@ public class PrivateTransactionValidator {
TransactionValidator.TransactionInvalidReason.PRIVATE_NONCE_TOO_LOW, errorMessage);
}
if (accountNonce != transactionNonce) {
if (!allowFutureNonces && accountNonce != transactionNonce) {
final String errorMessage =
String.format(
"Private Transaction nonce %s, does not match sender account nonce %s.",

@ -22,6 +22,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.INCORRECT_PRIVATE_NONCE;
import static org.hyperledger.besu.ethereum.mainnet.TransactionValidator.TransactionInvalidReason.PRIVATE_NONCE_TOO_LOW;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
@ -130,7 +131,7 @@ public class DefaultPrivacyControllerTest {
private PrivateTransactionValidator mockPrivateTransactionValidator() {
final PrivateTransactionValidator validator = mock(PrivateTransactionValidator.class);
when(validator.validate(any(), any())).thenReturn(ValidationResult.valid());
when(validator.validate(any(), any(), anyBoolean())).thenReturn(ValidationResult.valid());
return validator;
}
@ -264,7 +265,7 @@ public class DefaultPrivacyControllerTest {
@Test
public void validateTransactionWithTooLowNonceReturnsError() {
when(privateTransactionValidator.validate(any(), any()))
when(privateTransactionValidator.validate(any(), any(), anyBoolean()))
.thenReturn(ValidationResult.invalid(PRIVATE_NONCE_TOO_LOW));
final PrivateTransaction transaction = buildLegacyPrivateTransaction(0);
@ -275,7 +276,7 @@ public class DefaultPrivacyControllerTest {
@Test
public void validateTransactionWithIncorrectNonceReturnsError() {
when(privateTransactionValidator.validate(any(), any()))
when(privateTransactionValidator.validate(any(), any(), anyBoolean()))
.thenReturn(ValidationResult.invalid(INCORRECT_PRIVATE_NONCE));
final PrivateTransaction transaction = buildLegacyPrivateTransaction(2);

@ -49,25 +49,44 @@ public class PrivateTransactionValidatorTest {
}
@Test
public void transactionWithNonceLowerThanAccountNonceShouldReturnLowNonceError() {
public void transactionWithNonceLowerThanAccountNonceShouldAlwaysReturnLowNonceError() {
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithNonce(1L), 2L);
validator.validate(privateTransactionWithNonce(1L), 2L, false);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(PRIVATE_NONCE_TOO_LOW));
validationResult = validator.validate(privateTransactionWithNonce(1L), 2L, true);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(PRIVATE_NONCE_TOO_LOW));
}
@Test
public void transactionWithNonceGreaterThanAccountNonceShouldReturnIncorrectNonceError() {
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithNonce(3L), 2L);
public void
transactionWithNonceGreaterThanAccountNonceShouldReturnIncorrectNonceErrorWhenFutureNoncesNotAllowed() {
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithNonce(3L), 2L, false);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(INCORRECT_PRIVATE_NONCE));
}
@Test
public void transactionWithNonceMatchingThanAccountNonceShouldReturnValidTransactionResult() {
public void
transactionWithNonceGreaterThanAccountNonceShouldReturnValidTransactionWhenFutureNoncesAllowed() {
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithNonce(3L), 2L, true);
assertThat(validationResult).isEqualTo(ValidationResult.valid());
}
@Test
public void
transactionWithNonceMatchingThanAccountNonceShouldAlwaysReturnValidTransactionResult() {
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithNonce(1L), 1L);
validator.validate(privateTransactionWithNonce(1L), 1L, false);
assertThat(validationResult).isEqualTo(ValidationResult.valid());
validationResult = validator.validate(privateTransactionWithNonce(1L), 1L, true);
assertThat(validationResult).isEqualTo(ValidationResult.valid());
}
@ -76,8 +95,8 @@ public class PrivateTransactionValidatorTest {
public void transactionWithInvalidChainIdShouldReturnWrongChainId() {
validator = new PrivateTransactionValidator(Optional.of(BigInteger.ONE));
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithChainId(999), 0L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithChainId(999), 0L, false);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(WRONG_CHAIN_ID));
}
@ -87,8 +106,8 @@ public class PrivateTransactionValidatorTest {
transactionWithoutChainIdWithValidatorUsingChainIdShouldReturnReplayProtectedSignaturesNotSupported() {
validator = new PrivateTransactionValidator(Optional.empty());
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithChainId(999), 0L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithChainId(999), 0L, false);
assertThat(validationResult)
.isEqualTo(ValidationResult.invalid(REPLAY_PROTECTED_SIGNATURES_NOT_SUPPORTED));
@ -96,12 +115,12 @@ public class PrivateTransactionValidatorTest {
@Test
public void transactionWithInvalidSignatureShouldReturnInvalidSignature() {
PrivateTransaction transactionWithInvalidSignature =
final PrivateTransaction transactionWithInvalidSignature =
Mockito.spy(privateTransactionWithNonce(1L));
when(transactionWithInvalidSignature.getSender()).thenThrow(new IllegalArgumentException());
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(transactionWithInvalidSignature, 1L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(transactionWithInvalidSignature, 1L, false);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(INVALID_SIGNATURE));
}
@ -110,8 +129,8 @@ public class PrivateTransactionValidatorTest {
public void transactionWithNonZeroValueShouldReturnValueNotZeroError() {
validator = new PrivateTransactionValidator(Optional.of(BigInteger.ONE));
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithValue(1L), 0L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithValue(1L), 0L, false);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(PRIVATE_VALUE_NOT_ZERO));
}
@ -121,8 +140,8 @@ public class PrivateTransactionValidatorTest {
transactionWithUnrestrictedTransactionTypeShouldReturnUnimplementedTransactionTypeError() {
validator = new PrivateTransactionValidator(Optional.of(BigInteger.ONE));
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithRestriction(Restriction.UNRESTRICTED), 0L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithRestriction(Restriction.UNRESTRICTED), 0L, false);
assertThat(validationResult)
.isEqualTo(ValidationResult.invalid(PRIVATE_UNIMPLEMENTED_TRANSACTION_TYPE));
@ -133,8 +152,8 @@ public class PrivateTransactionValidatorTest {
transactionWithUnsupportedTransactionTypeShouldReturnUnimplementedTransactionTypeError() {
validator = new PrivateTransactionValidator(Optional.of(BigInteger.ONE));
ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithRestriction(Restriction.UNSUPPORTED), 0L);
final ValidationResult<TransactionInvalidReason> validationResult =
validator.validate(privateTransactionWithRestriction(Restriction.UNSUPPORTED), 0L, false);
assertThat(validationResult)
.isEqualTo(ValidationResult.invalid(PRIVATE_UNIMPLEMENTED_TRANSACTION_TYPE));

Loading…
Cancel
Save