Prioritize High Gas Price Transactions (#1449)

Prioritize high gas prices during mining. Previously we ordered only by 
the order in which the transactions were received. This will increase 
expected profit when mining.

Co-authored-by: Joshua Melton <jmelton@lawlogix.com>

Signed-off-by: Ratan Rai Sur <ratan.r.sur@gmail.com>
pull/1454/head
Ratan (Rai) Sur 4 years ago committed by GitHub
parent bbcc438244
commit e0e7a6fe5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 6
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactions.java
  3. 23
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionsTest.java

@ -3,6 +3,7 @@
### Additions and Improvements
* `--random-peer-priority-enabled` flag added. Allows for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. [#1440](https://github.com/hyperledger/besu/pull/1440)
* Hide deprecated `--host-whitelist` option. [\#1444](https://github.com/hyperledger/besu/pull/1444)
* Prioritize high gas prices during mining. Previously we ordered only by the order in which the transactions were received. This will increase expected profit when mining. [\#1449](https://github.com/hyperledger/besu/pull/1449)
## Deprecated and Scheduled for removal in _Next_ Release

@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.fees.EIP1559;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidator.TransactionInvalidReason;
import org.hyperledger.besu.metrics.BesuMetricCategory;
@ -71,6 +72,7 @@ public class PendingTransactions {
private final NavigableSet<TransactionInfo> prioritizedTransactions =
new TreeSet<>(
comparing(TransactionInfo::isReceivedFromLocalSource)
.thenComparing(TransactionInfo::getGasPrice)
.thenComparing(TransactionInfo::getSequence)
.reversed());
private final Map<Address, TransactionsForSenderInfo> transactionsBySender =
@ -402,6 +404,10 @@ public class PendingTransactions {
return transaction;
}
public Wei getGasPrice() {
return transaction.getGasPrice();
}
public long getSequence() {
return sequence;
}

@ -38,6 +38,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import com.google.common.collect.Lists;
import org.junit.Test;
@ -156,6 +158,27 @@ public class PendingTransactionsTest {
assertTransactionPending(localTransaction);
}
@Test
public void shouldPrioritizeGasPriceThenTimeAddedToPool() {
final List<Transaction> lowGasPriceTransactions =
IntStream.range(0, MAX_TRANSACTIONS)
.mapToObj(i -> transactionWithNonceSenderAndGasPrice(i + 1, KEYS1, 10))
.collect(Collectors.toUnmodifiableList());
// Fill the pool
lowGasPriceTransactions.forEach(transactions::addRemoteTransaction);
// This should kick the oldest tx with the low gas price out, namely the first one we added
final Transaction highGasPriceTransaction =
transactionWithNonceSenderAndGasPrice(MAX_TRANSACTIONS + 1, KEYS1, 100);
transactions.addRemoteTransaction(highGasPriceTransaction);
assertThat(transactions.size()).isEqualTo(MAX_TRANSACTIONS);
assertTransactionPending(highGasPriceTransaction);
assertTransactionNotPending(lowGasPriceTransactions.get(0));
lowGasPriceTransactions.stream().skip(1).forEach(this::assertTransactionPending);
}
@Test
public void shouldStartDroppingLocalTransactionsWhenPoolIsFullOfLocalTransactions() {
final Transaction firstLocalTransaction = createTransaction(0);

Loading…
Cancel
Save