|
|
@ -51,6 +51,7 @@ import org.hyperledger.besu.ethereum.core.Transaction; |
|
|
|
import org.hyperledger.besu.ethereum.core.TransactionReceipt; |
|
|
|
import org.hyperledger.besu.ethereum.core.TransactionReceipt; |
|
|
|
import org.hyperledger.besu.ethereum.core.TransactionTestFixture; |
|
|
|
import org.hyperledger.besu.ethereum.core.TransactionTestFixture; |
|
|
|
import org.hyperledger.besu.ethereum.core.Wei; |
|
|
|
import org.hyperledger.besu.ethereum.core.Wei; |
|
|
|
|
|
|
|
import org.hyperledger.besu.ethereum.core.fees.EIP1559; |
|
|
|
import org.hyperledger.besu.ethereum.eth.EthProtocol; |
|
|
|
import org.hyperledger.besu.ethereum.eth.EthProtocol; |
|
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthContext; |
|
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthContext; |
|
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; |
|
|
|
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; |
|
|
@ -66,6 +67,7 @@ import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; |
|
|
|
import org.hyperledger.besu.ethereum.mainnet.ValidationResult; |
|
|
|
import org.hyperledger.besu.ethereum.mainnet.ValidationResult; |
|
|
|
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; |
|
|
|
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; |
|
|
|
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; |
|
|
|
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; |
|
|
|
|
|
|
|
import org.hyperledger.besu.plugin.data.TransactionType; |
|
|
|
import org.hyperledger.besu.plugin.services.MetricsSystem; |
|
|
|
import org.hyperledger.besu.plugin.services.MetricsSystem; |
|
|
|
import org.hyperledger.besu.testutil.TestClock; |
|
|
|
import org.hyperledger.besu.testutil.TestClock; |
|
|
|
|
|
|
|
|
|
|
@ -704,6 +706,92 @@ public class TransactionPoolTest { |
|
|
|
.isTrue(); |
|
|
|
.isTrue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void shouldIgnoreEIP1559TransactionWhenNotAllowed() { |
|
|
|
|
|
|
|
final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create(); |
|
|
|
|
|
|
|
final EthContext ethContext = ethProtocolManager.ethContext(); |
|
|
|
|
|
|
|
final PeerTransactionTracker peerTransactionTracker = new PeerTransactionTracker(); |
|
|
|
|
|
|
|
final TransactionPool transactionPool = |
|
|
|
|
|
|
|
new TransactionPool( |
|
|
|
|
|
|
|
transactions, |
|
|
|
|
|
|
|
protocolSchedule, |
|
|
|
|
|
|
|
protocolContext, |
|
|
|
|
|
|
|
batchAddedListener, |
|
|
|
|
|
|
|
pendingBatchAddedListener, |
|
|
|
|
|
|
|
syncState, |
|
|
|
|
|
|
|
ethContext, |
|
|
|
|
|
|
|
peerTransactionTracker, |
|
|
|
|
|
|
|
peerPendingTransactionTracker, |
|
|
|
|
|
|
|
Wei.ZERO, |
|
|
|
|
|
|
|
metricsSystem, |
|
|
|
|
|
|
|
Optional.empty(), |
|
|
|
|
|
|
|
ImmutableTransactionPoolConfiguration.builder().txFeeCap(Wei.ONE).build()); |
|
|
|
|
|
|
|
when(transactionValidator.validate(any(Transaction.class), any(Optional.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
when(transactionValidator.validateForSender( |
|
|
|
|
|
|
|
any(Transaction.class), |
|
|
|
|
|
|
|
nullable(Account.class), |
|
|
|
|
|
|
|
any(TransactionValidationParams.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
final Transaction transaction = |
|
|
|
|
|
|
|
new TransactionTestFixture() |
|
|
|
|
|
|
|
.nonce(1) |
|
|
|
|
|
|
|
.type(TransactionType.EIP1559) |
|
|
|
|
|
|
|
.maxFeePerGas(Optional.of(Wei.ONE)) |
|
|
|
|
|
|
|
.maxPriorityFeePerGas(Optional.of(Wei.ONE)) |
|
|
|
|
|
|
|
.gasLimit(10) |
|
|
|
|
|
|
|
.gasPrice(null) |
|
|
|
|
|
|
|
.createTransaction(KEY_PAIR1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final ValidationResult<TransactionInvalidReason> result = |
|
|
|
|
|
|
|
transactionPool.addLocalTransaction(transaction); |
|
|
|
|
|
|
|
assertThat(result.getInvalidReason()) |
|
|
|
|
|
|
|
.isEqualTo(TransactionInvalidReason.INVALID_TRANSACTION_FORMAT); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void shouldIgnoreEIP1559TransactionBeforeTheFork() { |
|
|
|
|
|
|
|
final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create(); |
|
|
|
|
|
|
|
final EthContext ethContext = ethProtocolManager.ethContext(); |
|
|
|
|
|
|
|
final PeerTransactionTracker peerTransactionTracker = new PeerTransactionTracker(); |
|
|
|
|
|
|
|
final TransactionPool transactionPool = |
|
|
|
|
|
|
|
new TransactionPool( |
|
|
|
|
|
|
|
transactions, |
|
|
|
|
|
|
|
protocolSchedule, |
|
|
|
|
|
|
|
protocolContext, |
|
|
|
|
|
|
|
batchAddedListener, |
|
|
|
|
|
|
|
pendingBatchAddedListener, |
|
|
|
|
|
|
|
syncState, |
|
|
|
|
|
|
|
ethContext, |
|
|
|
|
|
|
|
peerTransactionTracker, |
|
|
|
|
|
|
|
peerPendingTransactionTracker, |
|
|
|
|
|
|
|
Wei.ZERO, |
|
|
|
|
|
|
|
metricsSystem, |
|
|
|
|
|
|
|
Optional.of(new EIP1559(100)), |
|
|
|
|
|
|
|
ImmutableTransactionPoolConfiguration.builder().txFeeCap(Wei.ONE).build()); |
|
|
|
|
|
|
|
when(transactionValidator.validate(any(Transaction.class), any(Optional.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
when(transactionValidator.validateForSender( |
|
|
|
|
|
|
|
any(Transaction.class), |
|
|
|
|
|
|
|
nullable(Account.class), |
|
|
|
|
|
|
|
any(TransactionValidationParams.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
final Transaction transaction = |
|
|
|
|
|
|
|
new TransactionTestFixture() |
|
|
|
|
|
|
|
.nonce(1) |
|
|
|
|
|
|
|
.type(TransactionType.EIP1559) |
|
|
|
|
|
|
|
.maxFeePerGas(Optional.of(Wei.ONE)) |
|
|
|
|
|
|
|
.maxPriorityFeePerGas(Optional.of(Wei.ONE)) |
|
|
|
|
|
|
|
.gasLimit(10) |
|
|
|
|
|
|
|
.gasPrice(null) |
|
|
|
|
|
|
|
.createTransaction(KEY_PAIR1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final ValidationResult<TransactionInvalidReason> result = |
|
|
|
|
|
|
|
transactionPool.addLocalTransaction(transaction); |
|
|
|
|
|
|
|
assertThat(result.getInvalidReason()) |
|
|
|
|
|
|
|
.isEqualTo(TransactionInvalidReason.INVALID_TRANSACTION_FORMAT); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void shouldRejectLocalTransactionIfFeeCapExceeded() { |
|
|
|
public void shouldRejectLocalTransactionIfFeeCapExceeded() { |
|
|
|
final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create(); |
|
|
|
final EthProtocolManager ethProtocolManager = EthProtocolManagerTestUtil.create(); |
|
|
@ -730,6 +818,14 @@ public class TransactionPoolTest { |
|
|
|
final Transaction transactionLocal = |
|
|
|
final Transaction transactionLocal = |
|
|
|
builder.nonce(1).gasPrice(twoEthers.add(Wei.of(1))).createTransaction(KEY_PAIR1); |
|
|
|
builder.nonce(1).gasPrice(twoEthers.add(Wei.of(1))).createTransaction(KEY_PAIR1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
when(transactionValidator.validate(any(Transaction.class), any(Optional.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
when(transactionValidator.validateForSender( |
|
|
|
|
|
|
|
any(Transaction.class), |
|
|
|
|
|
|
|
nullable(Account.class), |
|
|
|
|
|
|
|
any(TransactionValidationParams.class))) |
|
|
|
|
|
|
|
.thenReturn(valid()); |
|
|
|
|
|
|
|
|
|
|
|
final ValidationResult<TransactionInvalidReason> result = |
|
|
|
final ValidationResult<TransactionInvalidReason> result = |
|
|
|
transactionPool.addLocalTransaction(transactionLocal); |
|
|
|
transactionPool.addLocalTransaction(transactionLocal); |
|
|
|
assertThat(result.getInvalidReason()).isEqualTo(TransactionInvalidReason.TX_FEECAP_EXCEEDED); |
|
|
|
assertThat(result.getInvalidReason()).isEqualTo(TransactionInvalidReason.TX_FEECAP_EXCEEDED); |
|
|
|