Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
- Add TLS/mTLS options and configure the GraphQL HTTP service[#7910](https://github.com/hyperledger/besu/pull/7910)
- Update `eth_getLogs` to return a `Block not found` error when the requested block is not found. [#8290](https://github.com/hyperledger/besu/pull/8290)
- Change `Invalid block, unable to parse RLP` RPC error message to `Invalid block param (block not found)` [#8328](https://github.com/hyperledger/besu/pull/8328)
- Support pending transaction score when saving and restoring txpool [#8363](https://github.com/hyperledger/besu/pull/8363)

### Bug fixes
- Add missing RPC method `debug_accountRange` to `RpcMethod.java` so this method can be used with `--rpc-http-api-method-no-auth` [#8153](https://github.com/hyperledger/besu/issues/8153)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.fail;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
Expand Down Expand Up @@ -1080,7 +1081,8 @@ private PendingTransaction createLocalTransaction(final long transactionNumber)
.nonce(transactionNumber)
.createTransaction(KEYS1),
true,
true);
true,
MAX_SCORE);
}

private static BlockHeader mockBlockHeader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOBS_FULL;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_TOO_LARGE_FOR_REMAINING_BLOB_GAS;
Expand Down Expand Up @@ -172,12 +173,12 @@ private void evaluateAndAssertNotSelected(

private PendingTransaction createEIP1559PendingTransaction() {
return PendingTransaction.newPendingTransaction(
createTransaction(TransactionType.EIP1559, 0), false, false);
createTransaction(TransactionType.EIP1559, 0), false, false, MAX_SCORE);
}

private PendingTransaction createBlobPendingTransaction(final int blobCount) {
return PendingTransaction.newPendingTransaction(
createTransaction(TransactionType.BLOB, blobCount), false, false);
createTransaction(TransactionType.BLOB, blobCount), false, false, MAX_SCORE);
}

private Transaction createTransaction(final TransactionType type, final int blobCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.blockcreation.txselection.selectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_FULL;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_OCCUPANCY_ABOVE_THRESHOLD;
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED;
Expand Down Expand Up @@ -247,7 +248,7 @@ private void evaluateAndAssertNotSelected(

private PendingTransaction createPendingTransaction(final long gasLimit) {
return PendingTransaction.newPendingTransaction(
createTransaction(TransactionType.EIP1559, gasLimit), false, false);
createTransaction(TransactionType.EIP1559, gasLimit), false, false, MAX_SCORE);
}

private Transaction createTransaction(final TransactionType type, final long gasLimit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
*/
public abstract class PendingTransaction
implements org.hyperledger.besu.datatypes.PendingTransaction {
static final int NOT_INITIALIZED = -1;
public static final Byte MAX_SCORE = Byte.MAX_VALUE;
private static final int NOT_INITIALIZED = -1;
private static final AtomicLong TRANSACTIONS_ADDED = new AtomicLong();
private final Transaction transaction;
private final long addedAt;
Expand All @@ -58,37 +59,42 @@ public abstract class PendingTransaction
private int memorySize = NOT_INITIALIZED;

private PendingTransaction(
final Transaction transaction, final long addedAt, final long sequence, final byte score) {
final Transaction transaction, final byte score, final long addedAt, final long sequence) {
this.transaction = transaction;
this.addedAt = addedAt;
this.sequence = sequence;
this.score = score;
}

private PendingTransaction(final Transaction transaction, final long addedAt) {
this(transaction, addedAt, TRANSACTIONS_ADDED.getAndIncrement(), Byte.MAX_VALUE);
private PendingTransaction(final Transaction transaction, final byte score, final long addedAt) {
this(transaction, score, addedAt, TRANSACTIONS_ADDED.getAndIncrement());
}

public static PendingTransaction newPendingTransaction(
final Transaction transaction, final boolean isLocal, final boolean hasPriority) {
return newPendingTransaction(transaction, isLocal, hasPriority, System.currentTimeMillis());
final Transaction transaction,
final boolean isLocal,
final boolean hasPriority,
final byte score) {
return newPendingTransaction(
transaction, isLocal, hasPriority, score, System.currentTimeMillis());
}

public static PendingTransaction newPendingTransaction(
final Transaction transaction,
final boolean isLocal,
final boolean hasPriority,
final byte score,
final long addedAt) {
if (isLocal) {
if (hasPriority) {
return new Local.Priority(transaction, addedAt);
return new Local.Priority(transaction, score, addedAt);
}
return new Local(transaction, addedAt);
return new Local(transaction, score, addedAt);
}
if (hasPriority) {
return new Remote.Priority(transaction, addedAt);
return new Remote.Priority(transaction, score, addedAt);
}
return new Remote(transaction, addedAt);
return new Remote(transaction, score, addedAt);
}

@Override
Expand Down Expand Up @@ -311,16 +317,16 @@ public String toTraceLog() {

public static class Local extends PendingTransaction {

public Local(final Transaction transaction, final long addedAt) {
super(transaction, addedAt);
public Local(final Transaction transaction, final byte score, final long addedAt) {
super(transaction, score, addedAt);
}

public Local(final Transaction transaction) {
this(transaction, System.currentTimeMillis());
this(transaction, MAX_SCORE, System.currentTimeMillis());
}

private Local(final long sequence, final byte score, final Transaction transaction) {
super(transaction, System.currentTimeMillis(), sequence, score);
super(transaction, score, System.currentTimeMillis(), sequence);
}

@Override
Expand All @@ -340,11 +346,11 @@ public boolean hasPriority() {

public static class Priority extends Local {
public Priority(final Transaction transaction) {
this(transaction, System.currentTimeMillis());
this(transaction, MAX_SCORE, System.currentTimeMillis());
}

public Priority(final Transaction transaction, final long addedAt) {
super(transaction, addedAt);
public Priority(final Transaction transaction, final byte score, final long addedAt) {
super(transaction, score, addedAt);
}

public Priority(final long sequence, final byte score, final Transaction transaction) {
Expand All @@ -365,16 +371,16 @@ public boolean hasPriority() {

public static class Remote extends PendingTransaction {

public Remote(final Transaction transaction, final long addedAt) {
super(transaction, addedAt);
public Remote(final Transaction transaction, final byte score, final long addedAt) {
super(transaction, score, addedAt);
}

public Remote(final Transaction transaction) {
this(transaction, System.currentTimeMillis());
this(transaction, MAX_SCORE, System.currentTimeMillis());
}

private Remote(final long sequence, final byte score, final Transaction transaction) {
super(transaction, System.currentTimeMillis(), sequence, score);
super(transaction, score, System.currentTimeMillis(), sequence);
}

@Override
Expand All @@ -394,11 +400,11 @@ public boolean hasPriority() {

public static class Priority extends Remote {
public Priority(final Transaction transaction) {
this(transaction, System.currentTimeMillis());
this(transaction, MAX_SCORE, System.currentTimeMillis());
}

public Priority(final Transaction transaction, final long addedAt) {
super(transaction, addedAt);
public Priority(final Transaction transaction, final byte score, final long addedAt) {
super(transaction, score, addedAt);
}

public Priority(final long sequence, final byte score, final Transaction transaction) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.eth.transactions;

import static org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction.MAX_SCORE;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_NOT_AVAILABLE;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE;
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.INTERNAL_ERROR;
Expand All @@ -32,6 +33,8 @@
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.encoding.EncodingContext;
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
import org.hyperledger.besu.ethereum.eth.manager.EthContext;
import org.hyperledger.besu.ethereum.eth.manager.EthPeer;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
Expand Down Expand Up @@ -190,7 +193,7 @@ void handleConnect(final EthPeer peer) {
public ValidationResult<TransactionInvalidReason> addTransactionViaApi(
final Transaction transaction) {

final var result = addTransaction(transaction, true);
final var result = addTransaction(transaction, true, MAX_SCORE);
if (result.isValid()) {
localSenders.add(transaction.getSender());
transactionBroadcaster.onTransactionsAdded(List.of(transaction));
Expand All @@ -211,7 +214,7 @@ public Map<Hash, ValidationResult<TransactionInvalidReason>> addRemoteTransactio
Collectors.toMap(
Transaction::getHash,
transaction -> {
final var result = addTransaction(transaction, false);
final var result = addTransaction(transaction, false, MAX_SCORE);
if (result.isValid()) {
addedTransactions.add(transaction);
}
Expand Down Expand Up @@ -241,7 +244,7 @@ public Map<Hash, ValidationResult<TransactionInvalidReason>> addRemoteTransactio
}

private ValidationResult<TransactionInvalidReason> addTransaction(
final Transaction transaction, final boolean isLocal) {
final Transaction transaction, final boolean isLocal, final byte score) {

final boolean hasPriority = isPriorityTransaction(transaction, isLocal);

Expand All @@ -261,7 +264,7 @@ private ValidationResult<TransactionInvalidReason> addTransaction(
if (validationResult.result.isValid()) {
final TransactionAddedResult status =
pendingTransactions.addTransaction(
PendingTransaction.newPendingTransaction(transaction, isLocal, hasPriority),
PendingTransaction.newPendingTransaction(transaction, isLocal, hasPriority, score),
validationResult.maybeAccount);
if (status.isSuccess()) {
LOG.atTrace()
Expand Down Expand Up @@ -822,8 +825,10 @@ private void executeSaveToDisk(final PendingTransactions pendingTransactionsToSa
.map(
ptx -> {
final BytesValueRLPOutput rlp = new BytesValueRLPOutput();
ptx.getTransaction().writeTo(rlp);
return (ptx.isReceivedFromLocalSource() ? "l" : "r")
TransactionEncoder.encodeRLP(
ptx.getTransaction(), rlp, EncodingContext.POOLED_TRANSACTION);
return ptx.getScore()
+ (ptx.isReceivedFromLocalSource() ? "l" : "r")
+ rlp.encoded().toBase64String();
})
.mapToInt(
Expand Down Expand Up @@ -870,12 +875,16 @@ private void executeLoadFromDisk() {
.takeWhile(unused -> !isCancelled.get())
.map(
line -> {
final boolean isLocal = line.charAt(0) == 'l';
final var scoreStr = parseScore(line);
final byte score =
scoreStr.isEmpty() ? MAX_SCORE : Byte.parseByte(scoreStr);
final boolean isLocal = line.charAt(scoreStr.length()) == 'l';
final Transaction tx =
Transaction.readFrom(Bytes.fromBase64String(line.substring(1)));
Transaction.readFrom(
Bytes.fromBase64String(line.substring(scoreStr.length() + 1)));

final ValidationResult<TransactionInvalidReason> result =
addTransaction(tx, isLocal);
addTransaction(tx, isLocal, score);
return result.isValid() ? "OK" : result.getInvalidReason().name();
})
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Expand Down Expand Up @@ -909,6 +918,15 @@ private void executeLoadFromDisk() {
}
}

private String parseScore(final String line) {
int i = 0;
final var sbScore = new StringBuilder();
while ("1234567890-".indexOf(line.charAt(i)) >= 0) {
sbScore.append(line.charAt(i++));
}
return sbScore.toString();
}

private void removeProcessedLines(final File saveFile, final long processedLines)
throws IOException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,18 @@ protected void givenTransactionIsValid(final Transaction transaction) {
.thenReturn(valid());
}

protected void givenAllTransactionsAreValid() {
when(transactionValidatorFactory
.get()
.validate(any(), any(Optional.class), any(Optional.class), any()))
.thenReturn(valid());
when(transactionValidatorFactory
.get()
.validateForSender(
any(), nullable(Account.class), any(TransactionValidationParams.class)))
.thenReturn(valid());
}

protected abstract Block appendBlock(
final Difficulty difficulty,
final BlockHeader parentBlock,
Expand Down
Loading