Add a sender cache to Transaction (#6375)

Add a sender cache to Transaction.java, the senders and transactions' hashes are calculated when the transactions are decoded  from the newPayload.

Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
Co-authored-by: Fabio Di Fabio <fabio.difabio@consensys.net>
pull/6551/head
ahamlat 10 months ago committed by GitHub
parent 23aa99df3b
commit 40d1e7632d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 10
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java
  3. 8
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeMiningCoordinator.java
  4. 11
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java
  5. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineNewPayload.java
  6. 28
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
  7. 4
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/EthScheduler.java
  8. 2
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/SynchronizerConfiguration.java
  9. 10
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java
  10. 4
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransactionEstimatedMemorySizeTest.java

@ -93,6 +93,7 @@ https://hyperledger.jfrog.io/artifactory/besu-binaries/besu/24.1.1/besu-24.1.1.t
- Add custom genesis file name to config overview if specified [#6297](https://github.com/hyperledger/besu/pull/6297)
- Update Gradle plugins and replace unmaintained License Gradle Plugin with the actively maintained Gradle License Report [#6275](https://github.com/hyperledger/besu/pull/6275)
- Optimize RocksDB WAL files, allows for faster restart and a more linear disk space utilization [#6328](https://github.com/hyperledger/besu/pull/6328)
- Add a cache on senders by transaction hash [#6375](https://github.com/hyperledger/besu/pull/6375)
### Bug fixes
- Hotfix for selfdestruct preimages on bonsai [#6359]((https://github.com/hyperledger/besu/pull/6359)

@ -816,6 +816,16 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
});
}
/**
* returns the instance of ethScheduler
*
* @return get the Eth scheduler
*/
@Override
public EthScheduler getEthScheduler() {
return ethScheduler;
}
/** The interface Merge block creator factory. */
@FunctionalInterface
protected interface MergeBlockCreatorFactory {

@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import java.util.List;
import java.util.Optional;
@ -171,6 +172,13 @@ public interface MergeMiningCoordinator extends MiningCoordinator {
*/
void finalizeProposalById(final PayloadIdentifier payloadId);
/**
* Return the scheduler
*
* @return the instance of the scheduler
*/
EthScheduler getEthScheduler();
/** The type Forkchoice result. */
class ForkchoiceResult {
/** The enum Status. */

@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.eth.manager.EthScheduler;
import java.util.List;
import java.util.Optional;
@ -228,4 +229,14 @@ public class TransitionCoordinator extends TransitionUtils<MiningCoordinator>
public void finalizeProposalById(final PayloadIdentifier payloadId) {
mergeCoordinator.finalizeProposalById(payloadId);
}
/**
* returns the instance of ethScheduler
*
* @return get the Eth scheduler
*/
@Override
public EthScheduler getEthScheduler() {
return mergeCoordinator.getEthScheduler();
}
}

@ -25,6 +25,7 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType.INVALID_PARAMS;
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.BlobGas;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.VersionedHash;
@ -178,6 +179,19 @@ public abstract class AbstractEngineNewPayload extends ExecutionEngineJsonRpcMet
.map(Bytes::fromHexString)
.map(in -> TransactionDecoder.decodeOpaqueBytes(in, EncodingContext.BLOCK_BODY))
.collect(Collectors.toList());
transactions.forEach(
transaction ->
mergeCoordinator
.getEthScheduler()
.scheduleTxWorkerTask(
() -> {
Address sender = transaction.getSender();
LOG.atTrace()
.setMessage("The sender for transaction {} is calculated : {}")
.addArgument(transaction::getHash)
.addArgument(sender)
.log();
}));
} catch (final RLPException | IllegalArgumentException e) {
return respondWithInvalid(
reqId,

@ -51,6 +51,8 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.primitives.Longs;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
@ -75,6 +77,9 @@ public class Transaction
public static final BigInteger TWO = BigInteger.valueOf(2);
private static final Cache<Hash, Address> senderCache =
CacheBuilder.newBuilder().recordStats().maximumSize(100_000L).build();
private final long nonce;
private final Optional<Wei> gasPrice;
@ -411,18 +416,25 @@ public class Transaction
@Override
public Address getSender() {
if (sender == null) {
final SECPPublicKey publicKey =
signatureAlgorithm
.recoverPublicKeyFromSignature(getOrComputeSenderRecoveryHash(), signature)
.orElseThrow(
() ->
new IllegalStateException(
"Cannot recover public key from signature for " + this));
sender = Address.extract(Hash.hash(publicKey.getEncodedBytes()));
Optional<Address> cachedSender = Optional.ofNullable(senderCache.getIfPresent(getHash()));
sender = cachedSender.orElseGet(this::computeSender);
}
return sender;
}
private Address computeSender() {
final SECPPublicKey publicKey =
signatureAlgorithm
.recoverPublicKeyFromSignature(getOrComputeSenderRecoveryHash(), signature)
.orElseThrow(
() ->
new IllegalStateException(
"Cannot recover public key from signature for " + this));
final Address calculatedSender = Address.extract(Hash.hash(publicKey.getEncodedBytes()));
senderCache.put(this.hash, calculatedSender);
return calculatedSender;
}
/**
* Returns the public key extracted from the signature.
*

@ -146,6 +146,10 @@ public class EthScheduler {
servicesExecutor.execute(command);
}
public <T> CompletableFuture<Void> scheduleServiceTask(final Runnable task) {
return CompletableFuture.runAsync(task, servicesExecutor);
}
public <T> CompletableFuture<T> scheduleServiceTask(final EthTask<T> task) {
final CompletableFuture<T> serviceFuture = task.runAsync(servicesExecutor);
pendingFutures.add(serviceFuture);

@ -43,7 +43,7 @@ public class SynchronizerConfiguration {
public static final int DEFAULT_DOWNLOADER_CHECKPOINT_TIMEOUTS_PERMITTED = 5;
public static final int DEFAULT_DOWNLOADER_CHAIN_SEGMENT_SIZE = 200;
public static final int DEFAULT_DOWNLOADER_PARALLELISM = 4;
public static final int DEFAULT_TRANSACTIONS_PARALLELISM = 2;
public static final int DEFAULT_TRANSACTIONS_PARALLELISM = 4;
public static final int DEFAULT_COMPUTATION_PARALLELISM = 2;
public static final int DEFAULT_WORLD_STATE_TASK_CACHE_SIZE =
CachingTaskCollection.DEFAULT_CACHE_SIZE;

@ -31,8 +31,8 @@ import java.util.concurrent.atomic.AtomicLong;
public abstract class PendingTransaction
implements org.hyperledger.besu.datatypes.PendingTransaction {
static final int NOT_INITIALIZED = -1;
static final int FRONTIER_AND_ACCESS_LIST_BASE_MEMORY_SIZE = 872;
static final int EIP1559_AND_EIP4844_BASE_MEMORY_SIZE = 984;
static final int FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE = 888;
static final int EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE = 1000;
static final int OPTIONAL_TO_MEMORY_SIZE = 112;
static final int OPTIONAL_CHAIN_ID_MEMORY_SIZE = 80;
static final int PAYLOAD_BASE_MEMORY_SIZE = 32;
@ -136,14 +136,14 @@ public abstract class PendingTransaction
}
private int computeFrontierMemorySize() {
return FRONTIER_AND_ACCESS_LIST_BASE_MEMORY_SIZE
return FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE
+ computePayloadMemorySize()
+ computeToMemorySize()
+ computeChainIdMemorySize();
}
private int computeAccessListMemorySize() {
return FRONTIER_AND_ACCESS_LIST_BASE_MEMORY_SIZE
return FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE
+ computePayloadMemorySize()
+ computeToMemorySize()
+ computeChainIdMemorySize()
@ -151,7 +151,7 @@ public abstract class PendingTransaction
}
private int computeEIP1559MemorySize() {
return EIP1559_AND_EIP4844_BASE_MEMORY_SIZE
return EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE
+ computePayloadMemorySize()
+ computeToMemorySize()
+ computeChainIdMemorySize()

@ -381,7 +381,7 @@ public class PendingTransactionEstimatedMemorySizeTest extends BaseTransactionPo
System.out.println("Base EIP1559 size: " + eip1559size);
assertThat(eip1559size.sum())
.isEqualTo(PendingTransaction.EIP1559_AND_EIP4844_BASE_MEMORY_SIZE);
.isEqualTo(PendingTransaction.EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE);
}
@Test
@ -426,7 +426,7 @@ public class PendingTransactionEstimatedMemorySizeTest extends BaseTransactionPo
System.out.println("Base Frontier size: " + frontierSize);
assertThat(frontierSize.sum())
.isEqualTo(PendingTransaction.FRONTIER_AND_ACCESS_LIST_BASE_MEMORY_SIZE);
.isEqualTo(PendingTransaction.FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE);
}
private GraphWalker getGraphWalker(

Loading…
Cancel
Save