From 2bf32b1fe6aa9081cb5b0fec5ba2c37c4f34c4d8 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Thu, 5 Dec 2024 14:44:21 +1100 Subject: [PATCH 01/20] 7582: Add naive RLP caching for BlockHeader, Transaction, and Withdrawal Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/BlockHeader.java | 155 +++++++++++------- .../besu/ethereum/core/Transaction.java | 26 ++- .../besu/ethereum/core/Withdrawal.java | 13 +- .../core/encoding/WithdrawalDecoder.java | 17 +- .../core/encoding/WithdrawalEncoder.java | 14 +- .../core/encoding/WithdrawalDecoderTest.java | 1 + .../core/encoding/WithdrawalEncoderTest.java | 16 ++ .../eth/transactions/PendingTransaction.java | 4 +- 8 files changed, 166 insertions(+), 80 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 830a80ccceb..c689b1ef783 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.util.Objects; +import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -44,6 +45,36 @@ public class BlockHeader extends SealableBlockHeader private final Supplier parsedExtraData; + private final Optional rawRlp; + + public BlockHeader( + final Hash parentHash, + final Hash ommersHash, + final Address coinbase, + final Hash stateRoot, + final Hash transactionsRoot, + final Hash receiptsRoot, + final LogsBloomFilter logsBloom, + final Difficulty difficulty, + final long number, + final long gasLimit, + final long gasUsed, + final long timestamp, + final Bytes extraData, + final Wei baseFee, + final Bytes32 mixHashOrPrevRandao, + final long nonce, + final Hash withdrawalsRoot, + final Long blobGasUsed, + final BlobGas excessBlobGas, + final Bytes32 parentBeaconBlockRoot, + final Hash requestsHash, + final UInt64 targetBlobCount, + final BlockHeaderFunctions blockHeaderFunctions) { + this(parentHash, ommersHash, coinbase, stateRoot, transactionsRoot, receiptsRoot, logsBloom, difficulty, number, gasLimit, gasUsed, timestamp, extraData, baseFee, + mixHashOrPrevRandao, nonce, withdrawalsRoot, blobGasUsed, excessBlobGas, parentBeaconBlockRoot, requestsHash, targetBlobCount, blockHeaderFunctions, Optional.empty()); + } + public BlockHeader( final Hash parentHash, final Hash ommersHash, @@ -67,7 +98,8 @@ public BlockHeader( final Bytes32 parentBeaconBlockRoot, final Hash requestsHash, final UInt64 targetBlobCount, - final BlockHeaderFunctions blockHeaderFunctions) { + final BlockHeaderFunctions blockHeaderFunctions, + final Optional rawRlp) { super( parentHash, ommersHash, @@ -93,6 +125,7 @@ public BlockHeader( this.nonce = nonce; this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this)); this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this)); + this.rawRlp = rawRlp; } public static boolean hasEmptyBlock(final BlockHeader blockHeader) { @@ -157,76 +190,79 @@ public Hash getBlockHash() { * @param out The RLP output to write to */ public void writeTo(final RLPOutput out) { - out.startList(); + rawRlp.ifPresentOrElse(out::writeRLPBytes, () -> { + out.startList(); - out.writeBytes(parentHash); - out.writeBytes(ommersHash); - out.writeBytes(coinbase); - out.writeBytes(stateRoot); - out.writeBytes(transactionsRoot); - out.writeBytes(receiptsRoot); - out.writeBytes(logsBloom); - out.writeUInt256Scalar(difficulty); - out.writeLongScalar(number); - out.writeLongScalar(gasLimit); - out.writeLongScalar(gasUsed); - out.writeLongScalar(timestamp); - out.writeBytes(extraData); - out.writeBytes(mixHashOrPrevRandao); - out.writeLong(nonce); - do { - if (baseFee == null) break; - out.writeUInt256Scalar(baseFee); + out.writeBytes(parentHash); + out.writeBytes(ommersHash); + out.writeBytes(coinbase); + out.writeBytes(stateRoot); + out.writeBytes(transactionsRoot); + out.writeBytes(receiptsRoot); + out.writeBytes(logsBloom); + out.writeUInt256Scalar(difficulty); + out.writeLongScalar(number); + out.writeLongScalar(gasLimit); + out.writeLongScalar(gasUsed); + out.writeLongScalar(timestamp); + out.writeBytes(extraData); + out.writeBytes(mixHashOrPrevRandao); + out.writeLong(nonce); + do { + if (baseFee == null) break; + out.writeUInt256Scalar(baseFee); - if (withdrawalsRoot == null) break; - out.writeBytes(withdrawalsRoot); + if (withdrawalsRoot == null) break; + out.writeBytes(withdrawalsRoot); - if (excessBlobGas == null || blobGasUsed == null) break; - out.writeLongScalar(blobGasUsed); - out.writeUInt64Scalar(excessBlobGas); + if (excessBlobGas == null || blobGasUsed == null) break; + out.writeLongScalar(blobGasUsed); + out.writeUInt64Scalar(excessBlobGas); - if (parentBeaconBlockRoot == null) break; - out.writeBytes(parentBeaconBlockRoot); + if (parentBeaconBlockRoot == null) break; + out.writeBytes(parentBeaconBlockRoot); - if (requestsHash == null) break; - out.writeBytes(requestsHash); + if (requestsHash == null) break; + out.writeBytes(requestsHash); - if (targetBlobCount == null) break; - out.writeUInt64Scalar(targetBlobCount); - } while (false); - out.endList(); + if (targetBlobCount == null) break; + out.writeUInt64Scalar(targetBlobCount); + } while (false); + out.endList(); + }); } public static BlockHeader readFrom( final RLPInput input, final BlockHeaderFunctions blockHeaderFunctions) { - input.enterList(); - final Hash parentHash = Hash.wrap(input.readBytes32()); - final Hash ommersHash = Hash.wrap(input.readBytes32()); - final Address coinbase = Address.readFrom(input); - final Hash stateRoot = Hash.wrap(input.readBytes32()); - final Hash transactionsRoot = Hash.wrap(input.readBytes32()); - final Hash receiptsRoot = Hash.wrap(input.readBytes32()); - final LogsBloomFilter logsBloom = LogsBloomFilter.readFrom(input); - final Difficulty difficulty = Difficulty.of(input.readUInt256Scalar()); - final long number = input.readLongScalar(); - final long gasLimit = input.readLongScalar(); - final long gasUsed = input.readLongScalar(); - final long timestamp = input.readLongScalar(); - final Bytes extraData = input.readBytes(); - final Bytes32 mixHashOrPrevRandao = input.readBytes32(); - final long nonce = input.readLong(); - final Wei baseFee = !input.isEndOfCurrentList() ? Wei.of(input.readUInt256Scalar()) : null; + final RLPInput headerRlp = input.readAsRlp(); + headerRlp.enterList(); + final Hash parentHash = Hash.wrap(headerRlp.readBytes32()); + final Hash ommersHash = Hash.wrap(headerRlp.readBytes32()); + final Address coinbase = Address.readFrom(headerRlp); + final Hash stateRoot = Hash.wrap(headerRlp.readBytes32()); + final Hash transactionsRoot = Hash.wrap(headerRlp.readBytes32()); + final Hash receiptsRoot = Hash.wrap(headerRlp.readBytes32()); + final LogsBloomFilter logsBloom = LogsBloomFilter.readFrom(headerRlp); + final Difficulty difficulty = Difficulty.of(headerRlp.readUInt256Scalar()); + final long number = headerRlp.readLongScalar(); + final long gasLimit = headerRlp.readLongScalar(); + final long gasUsed = headerRlp.readLongScalar(); + final long timestamp = headerRlp.readLongScalar(); + final Bytes extraData = headerRlp.readBytes(); + final Bytes32 mixHashOrPrevRandao = headerRlp.readBytes32(); + final long nonce = headerRlp.readLong(); + final Wei baseFee = !headerRlp.isEndOfCurrentList() ? Wei.of(headerRlp.readUInt256Scalar()) : null; final Hash withdrawalHashRoot = - !(input.isEndOfCurrentList() || input.isZeroLengthString()) - ? Hash.wrap(input.readBytes32()) + !(headerRlp.isEndOfCurrentList() || headerRlp.isZeroLengthString()) + ? Hash.wrap(headerRlp.readBytes32()) : null; - final Long blobGasUsed = !input.isEndOfCurrentList() ? input.readLongScalar() : null; + final Long blobGasUsed = !headerRlp.isEndOfCurrentList() ? headerRlp.readLongScalar() : null; final BlobGas excessBlobGas = - !input.isEndOfCurrentList() ? BlobGas.of(input.readUInt64Scalar()) : null; - final Bytes32 parentBeaconBlockRoot = !input.isEndOfCurrentList() ? input.readBytes32() : null; - final Hash requestsHash = !input.isEndOfCurrentList() ? Hash.wrap(input.readBytes32()) : null; - final UInt64 targetBlobCount = !input.isEndOfCurrentList() ? input.readUInt64Scalar() : null; - input.leaveList(); + !headerRlp.isEndOfCurrentList() ? BlobGas.of(headerRlp.readUInt64Scalar()) : null; + final Bytes32 parentBeaconBlockRoot = !headerRlp.isEndOfCurrentList() ? headerRlp.readBytes32() : null; + final Hash requestsHash = !headerRlp.isEndOfCurrentList() ? Hash.wrap(headerRlp.readBytes32()) : null; + final UInt64 targetBlobCount = !headerRlp.isEndOfCurrentList() ? headerRlp.readUInt64Scalar() : null; + headerRlp.leaveList(); return new BlockHeader( parentHash, ommersHash, @@ -250,7 +286,8 @@ public static BlockHeader readFrom( parentBeaconBlockRoot, requestsHash, targetBlobCount, - blockHeaderFunctions); + blockHeaderFunctions, + Optional.of(headerRlp.raw())); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index 0da8f8f28a2..4d9c1ba3205 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -60,6 +60,8 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256s; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** An operation submitted by an external actor to be applied to the system. */ public class Transaction @@ -126,6 +128,8 @@ public class Transaction private final Optional blobsWithCommitments; private final Optional> maybeCodeDelegationList; + private final Optional rawRlp; + public static Builder builder() { return new Builder(); } @@ -135,7 +139,9 @@ public static Transaction readFrom(final Bytes rlpBytes) { } public static Transaction readFrom(final RLPInput rlpInput) { - return TransactionDecoder.decodeRLP(rlpInput, EncodingContext.BLOCK_BODY); + RLPInput transactionRlp = rlpInput.readAsRlp(); + Transaction transaction = TransactionDecoder.decodeRLP(transactionRlp, EncodingContext.BLOCK_BODY); + return Transaction.builder().copiedFrom(transaction).rawRlp(Optional.of(transactionRlp.raw())).build(); } /** @@ -181,7 +187,8 @@ private Transaction( final Optional chainId, final Optional> versionedHashes, final Optional blobsWithCommitments, - final Optional> maybeCodeDelegationList) { + final Optional> maybeCodeDelegationList, + final Optional rawRlp) { if (!forCopy) { if (transactionType.requiresChainId()) { @@ -242,6 +249,7 @@ private Transaction( this.versionedHashes = versionedHashes; this.blobsWithCommitments = blobsWithCommitments; this.maybeCodeDelegationList = maybeCodeDelegationList; + this.rawRlp = rawRlp; } /** @@ -485,7 +493,7 @@ private Bytes32 getOrComputeSenderRecoveryHash() { * @param out the output to write the transaction to */ public void writeTo(final RLPOutput out) { - TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY); + rawRlp.ifPresentOrElse(out::writeRLPBytes, () -> TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY)); } @Override @@ -1111,7 +1119,8 @@ public Transaction detachedCopy() { chainId, detachedVersionedHashes, detachedBlobsWithCommitments, - maybeCodeDelegationList); + maybeCodeDelegationList, + Optional.empty()); // copy also the computed fields, to avoid to recompute them copiedTx.sender = this.sender; @@ -1180,6 +1189,7 @@ public static class Builder { protected List versionedHashes = null; private BlobsWithCommitments blobsWithCommitments; protected Optional> codeDelegationAuthorizations = Optional.empty(); + protected Optional rawRlp = Optional.empty(); public Builder copiedFrom(final Transaction toCopy) { this.transactionType = toCopy.transactionType; @@ -1285,6 +1295,11 @@ public Builder versionedHashes(final List versionedHashes) { return this; } + public Builder rawRlp(final Optional rawRlp) { + this.rawRlp = rawRlp; + return this; + } + public Builder guessType() { if (versionedHashes != null && !versionedHashes.isEmpty()) { transactionType = TransactionType.BLOB; @@ -1324,7 +1339,8 @@ public Transaction build() { chainId, Optional.ofNullable(versionedHashes), Optional.ofNullable(blobsWithCommitments), - codeDelegationAuthorizations); + codeDelegationAuthorizations, + rawRlp); } public Transaction signAndBuild(final KeyPair keys) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java index b82eda72481..f506eadbbeb 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput; import java.util.Objects; +import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; @@ -32,13 +33,19 @@ public class Withdrawal implements org.hyperledger.besu.plugin.data.Withdrawal { private final UInt64 validatorIndex; private final Address address; private final GWei amount; + private final Optional rawRlp; public Withdrawal( - final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount) { + final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount) { + this(index, validatorIndex, address, amount, Optional.empty()); + } + public Withdrawal( + final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount, final Optional rawRlp) { this.index = index; this.validatorIndex = validatorIndex; this.address = address; this.amount = amount; + this.rawRlp = rawRlp; } public static Withdrawal readFrom(final Bytes rlpBytes) { @@ -73,6 +80,10 @@ public GWei getAmount() { return amount; } + public Optional getRawRlp() { + return rawRlp; + } + @Override public String toString() { return "Withdrawal{" diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java index c2e98215b73..119712c7639 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java @@ -23,17 +23,20 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; +import java.util.Optional; + public class WithdrawalDecoder { public static Withdrawal decode(final RLPInput rlpInput) { - rlpInput.enterList(); - final UInt64 index = UInt64.valueOf(rlpInput.readBigIntegerScalar()); - final UInt64 validatorIndex = UInt64.valueOf(rlpInput.readBigIntegerScalar()); - final Address address = Address.readFrom(rlpInput); - final GWei amount = GWei.of(rlpInput.readUInt64Scalar()); - rlpInput.leaveList(); + final RLPInput withdrawalRlp = rlpInput.readAsRlp(); + withdrawalRlp.enterList(); + final UInt64 index = UInt64.valueOf(withdrawalRlp.readBigIntegerScalar()); + final UInt64 validatorIndex = UInt64.valueOf(withdrawalRlp.readBigIntegerScalar()); + final Address address = Address.readFrom(withdrawalRlp); + final GWei amount = GWei.of(withdrawalRlp.readUInt64Scalar()); + withdrawalRlp.leaveList(); - return new Withdrawal(index, validatorIndex, address, amount); + return new Withdrawal(index, validatorIndex, address, amount, Optional.of(withdrawalRlp.raw())); } public static Withdrawal decodeOpaqueBytes(final Bytes input) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java index 27d6b805cb8..7f8f5ea98b9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java @@ -23,12 +23,14 @@ public class WithdrawalEncoder { public static void encode(final Withdrawal withdrawal, final RLPOutput rlpOutput) { - rlpOutput.startList(); - rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); - rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); - rlpOutput.writeBytes(withdrawal.getAddress()); - rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); - rlpOutput.endList(); + withdrawal.getRawRlp().ifPresentOrElse(rlpOutput::writeRLPBytes, () -> { + rlpOutput.startList(); + rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); + rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); + rlpOutput.writeBytes(withdrawal.getAddress()); + rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); + rlpOutput.endList(); + }); } public static Bytes encodeOpaqueBytes(final Withdrawal withdrawal) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java index 9ffd219db0a..0bd5cd4ffbb 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java @@ -58,5 +58,6 @@ void shouldDecodeWithdrawal() { Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); assertThat(withdrawal).isEqualTo(expectedWithdrawal); + assertThat(withdrawal.getRawRlp().get()).isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java index 3e4d81f02be..e7cc9bbcb48 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java @@ -24,6 +24,8 @@ import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; +import java.util.Optional; + class WithdrawalEncoderTest { public static final String WITHDRAWAL_ZERO_CASE = "0xd8808094000000000000000000000000000000000000000080"; @@ -58,4 +60,18 @@ void shouldEncode() { assertThat(encoded) .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } + + @Test + public void shouldEncodeFromRawRlp() { + final UInt64 index = UInt64.valueOf(1); + final UInt64 validatorIndex = UInt64.valueOf(2); + final Address address = Address.fromHexString("0xffffffff"); + final GWei amount = GWei.of(3); + final Withdrawal withdrawal = new Withdrawal(index, validatorIndex, address, amount, Optional.of(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05"))); + + final Bytes encoded = WithdrawalEncoder.encodeOpaqueBytes(withdrawal); + + assertThat(encoded) + .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); + } } diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index 91b4efd7b21..839e82145e5 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -31,8 +31,8 @@ public abstract class PendingTransaction implements org.hyperledger.besu.datatypes.PendingTransaction { static final int NOT_INITIALIZED = -1; - static final int FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE = 904; - static final int EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE = 1016; + static final int FRONTIER_AND_ACCESS_LIST_SHALLOW_MEMORY_SIZE = 912; + static final int EIP1559_AND_EIP4844_SHALLOW_MEMORY_SIZE = 1024; 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; From eebbab3e76bfe2bafa04d1e4f23021783a9a7355 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Thu, 5 Dec 2024 15:46:09 +1100 Subject: [PATCH 02/20] 7582: spotless Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/BlockHeader.java | 157 +++++++++++------- .../besu/ethereum/core/Transaction.java | 18 +- .../besu/ethereum/core/Withdrawal.java | 9 +- .../core/encoding/WithdrawalDecoder.java | 4 +- .../core/encoding/WithdrawalEncoder.java | 20 ++- .../core/encoding/WithdrawalDecoderTest.java | 3 +- .../core/encoding/WithdrawalEncoderTest.java | 15 +- 7 files changed, 138 insertions(+), 88 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 2bcde0a7a58..d8d124f3a9f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -48,31 +48,54 @@ public class BlockHeader extends SealableBlockHeader private final Optional rawRlp; public BlockHeader( - final Hash parentHash, - final Hash ommersHash, - final Address coinbase, - final Hash stateRoot, - final Hash transactionsRoot, - final Hash receiptsRoot, - final LogsBloomFilter logsBloom, - final Difficulty difficulty, - final long number, - final long gasLimit, - final long gasUsed, - final long timestamp, - final Bytes extraData, - final Wei baseFee, - final Bytes32 mixHashOrPrevRandao, - final long nonce, - final Hash withdrawalsRoot, - final Long blobGasUsed, - final BlobGas excessBlobGas, - final Bytes32 parentBeaconBlockRoot, - final Hash requestsHash, - final UInt64 targetBlobsPerBlock, - final BlockHeaderFunctions blockHeaderFunctions) { - this(parentHash, ommersHash, coinbase, stateRoot, transactionsRoot, receiptsRoot, logsBloom, difficulty, number, gasLimit, gasUsed, timestamp, extraData, baseFee, - mixHashOrPrevRandao, nonce, withdrawalsRoot, blobGasUsed, excessBlobGas, parentBeaconBlockRoot, requestsHash, targetBlobsPerBlock, blockHeaderFunctions, Optional.empty()); + final Hash parentHash, + final Hash ommersHash, + final Address coinbase, + final Hash stateRoot, + final Hash transactionsRoot, + final Hash receiptsRoot, + final LogsBloomFilter logsBloom, + final Difficulty difficulty, + final long number, + final long gasLimit, + final long gasUsed, + final long timestamp, + final Bytes extraData, + final Wei baseFee, + final Bytes32 mixHashOrPrevRandao, + final long nonce, + final Hash withdrawalsRoot, + final Long blobGasUsed, + final BlobGas excessBlobGas, + final Bytes32 parentBeaconBlockRoot, + final Hash requestsHash, + final UInt64 targetBlobsPerBlock, + final BlockHeaderFunctions blockHeaderFunctions) { + this( + parentHash, + ommersHash, + coinbase, + stateRoot, + transactionsRoot, + receiptsRoot, + logsBloom, + difficulty, + number, + gasLimit, + gasUsed, + timestamp, + extraData, + baseFee, + mixHashOrPrevRandao, + nonce, + withdrawalsRoot, + blobGasUsed, + excessBlobGas, + parentBeaconBlockRoot, + requestsHash, + targetBlobsPerBlock, + blockHeaderFunctions, + Optional.empty()); } public BlockHeader( @@ -190,46 +213,48 @@ public Hash getBlockHash() { * @param out The RLP output to write to */ public void writeTo(final RLPOutput out) { - rawRlp.ifPresentOrElse(out::writeRLPBytes, () -> { - out.startList(); + rawRlp.ifPresentOrElse( + out::writeRLPBytes, + () -> { + out.startList(); - out.writeBytes(parentHash); - out.writeBytes(ommersHash); - out.writeBytes(coinbase); - out.writeBytes(stateRoot); - out.writeBytes(transactionsRoot); - out.writeBytes(receiptsRoot); - out.writeBytes(logsBloom); - out.writeUInt256Scalar(difficulty); - out.writeLongScalar(number); - out.writeLongScalar(gasLimit); - out.writeLongScalar(gasUsed); - out.writeLongScalar(timestamp); - out.writeBytes(extraData); - out.writeBytes(mixHashOrPrevRandao); - out.writeLong(nonce); - do { - if (baseFee == null) break; - out.writeUInt256Scalar(baseFee); + out.writeBytes(parentHash); + out.writeBytes(ommersHash); + out.writeBytes(coinbase); + out.writeBytes(stateRoot); + out.writeBytes(transactionsRoot); + out.writeBytes(receiptsRoot); + out.writeBytes(logsBloom); + out.writeUInt256Scalar(difficulty); + out.writeLongScalar(number); + out.writeLongScalar(gasLimit); + out.writeLongScalar(gasUsed); + out.writeLongScalar(timestamp); + out.writeBytes(extraData); + out.writeBytes(mixHashOrPrevRandao); + out.writeLong(nonce); + do { + if (baseFee == null) break; + out.writeUInt256Scalar(baseFee); - if (withdrawalsRoot == null) break; - out.writeBytes(withdrawalsRoot); + if (withdrawalsRoot == null) break; + out.writeBytes(withdrawalsRoot); - if (excessBlobGas == null || blobGasUsed == null) break; - out.writeLongScalar(blobGasUsed); - out.writeUInt64Scalar(excessBlobGas); + if (excessBlobGas == null || blobGasUsed == null) break; + out.writeLongScalar(blobGasUsed); + out.writeUInt64Scalar(excessBlobGas); - if (parentBeaconBlockRoot == null) break; - out.writeBytes(parentBeaconBlockRoot); + if (parentBeaconBlockRoot == null) break; + out.writeBytes(parentBeaconBlockRoot); - if (requestsHash == null) break; - out.writeBytes(requestsHash); + if (requestsHash == null) break; + out.writeBytes(requestsHash); - if (targetBlobsPerBlock == null) break; - out.writeUInt64Scalar(targetBlobsPerBlock); - } while (false); - out.endList(); - }); + if (targetBlobsPerBlock == null) break; + out.writeUInt64Scalar(targetBlobsPerBlock); + } while (false); + out.endList(); + }); } public static BlockHeader readFrom( @@ -251,7 +276,8 @@ public static BlockHeader readFrom( final Bytes extraData = headerRlp.readBytes(); final Bytes32 mixHashOrPrevRandao = headerRlp.readBytes32(); final long nonce = headerRlp.readLong(); - final Wei baseFee = !headerRlp.isEndOfCurrentList() ? Wei.of(headerRlp.readUInt256Scalar()) : null; + final Wei baseFee = + !headerRlp.isEndOfCurrentList() ? Wei.of(headerRlp.readUInt256Scalar()) : null; final Hash withdrawalHashRoot = !(headerRlp.isEndOfCurrentList() || headerRlp.isZeroLengthString()) ? Hash.wrap(headerRlp.readBytes32()) @@ -259,9 +285,12 @@ public static BlockHeader readFrom( final Long blobGasUsed = !headerRlp.isEndOfCurrentList() ? headerRlp.readLongScalar() : null; final BlobGas excessBlobGas = !headerRlp.isEndOfCurrentList() ? BlobGas.of(headerRlp.readUInt64Scalar()) : null; - final Bytes32 parentBeaconBlockRoot = !headerRlp.isEndOfCurrentList() ? headerRlp.readBytes32() : null; - final Hash requestsHash = !headerRlp.isEndOfCurrentList() ? Hash.wrap(headerRlp.readBytes32()) : null; - final UInt64 targetBlobsPerBlock = !headerRlp.isEndOfCurrentList() ? headerRlp.readUInt64Scalar() : null; + final Bytes32 parentBeaconBlockRoot = + !headerRlp.isEndOfCurrentList() ? headerRlp.readBytes32() : null; + final Hash requestsHash = + !headerRlp.isEndOfCurrentList() ? Hash.wrap(headerRlp.readBytes32()) : null; + final UInt64 targetBlobsPerBlock = + !headerRlp.isEndOfCurrentList() ? headerRlp.readUInt64Scalar() : null; headerRlp.leaveList(); return new BlockHeader( parentHash, @@ -285,7 +314,7 @@ public static BlockHeader readFrom( excessBlobGas, parentBeaconBlockRoot, requestsHash, - targetBlobsPerBlock, + targetBlobsPerBlock, blockHeaderFunctions, Optional.of(headerRlp.raw())); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index 203f1a4782e..dd6151a5a0c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -60,8 +60,6 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256s; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** An operation submitted by an external actor to be applied to the system. */ public class Transaction @@ -140,8 +138,12 @@ public static Transaction readFrom(final Bytes rlpBytes) { public static Transaction readFrom(final RLPInput rlpInput) { RLPInput transactionRlp = rlpInput.readAsRlp(); - Transaction transaction = TransactionDecoder.decodeRLP(transactionRlp, EncodingContext.BLOCK_BODY); - return Transaction.builder().copiedFrom(transaction).rawRlp(Optional.of(transactionRlp.raw())).build(); + Transaction transaction = + TransactionDecoder.decodeRLP(transactionRlp, EncodingContext.BLOCK_BODY); + return Transaction.builder() + .copiedFrom(transaction) + .rawRlp(Optional.of(transactionRlp.raw())) + .build(); } /** @@ -493,7 +495,9 @@ private Bytes32 getOrComputeSenderRecoveryHash() { * @param out the output to write the transaction to */ public void writeTo(final RLPOutput out) { - rawRlp.ifPresentOrElse(out::writeRLPBytes, () -> TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY)); + rawRlp.ifPresentOrElse( + out::writeRLPBytes, + () -> TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY)); } @Override @@ -1121,7 +1125,7 @@ public Transaction detachedCopy() { detachedVersionedHashes, detachedBlobsWithCommitments, maybeCodeDelegationList, - Optional.empty()); + Optional.empty()); // copy also the computed fields, to avoid to recompute them copiedTx.sender = this.sender; @@ -1341,7 +1345,7 @@ public Transaction build() { Optional.ofNullable(versionedHashes), Optional.ofNullable(blobsWithCommitments), codeDelegationAuthorizations, - rawRlp); + rawRlp); } public Transaction signAndBuild(final KeyPair keys) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java index f506eadbbeb..ceef9c8b5a5 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java @@ -36,11 +36,16 @@ public class Withdrawal implements org.hyperledger.besu.plugin.data.Withdrawal { private final Optional rawRlp; public Withdrawal( - final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount) { + final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount) { this(index, validatorIndex, address, amount, Optional.empty()); } + public Withdrawal( - final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount, final Optional rawRlp) { + final UInt64 index, + final UInt64 validatorIndex, + final Address address, + final GWei amount, + final Optional rawRlp) { this.index = index; this.validatorIndex = validatorIndex; this.address = address; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java index 119712c7639..9079bd7b495 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java @@ -20,11 +20,11 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; +import java.util.Optional; + import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; -import java.util.Optional; - public class WithdrawalDecoder { public static Withdrawal decode(final RLPInput rlpInput) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java index 7f8f5ea98b9..87af3a2fef3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java @@ -23,14 +23,18 @@ public class WithdrawalEncoder { public static void encode(final Withdrawal withdrawal, final RLPOutput rlpOutput) { - withdrawal.getRawRlp().ifPresentOrElse(rlpOutput::writeRLPBytes, () -> { - rlpOutput.startList(); - rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); - rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); - rlpOutput.writeBytes(withdrawal.getAddress()); - rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); - rlpOutput.endList(); - }); + withdrawal + .getRawRlp() + .ifPresentOrElse( + rlpOutput::writeRLPBytes, + () -> { + rlpOutput.startList(); + rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); + rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); + rlpOutput.writeBytes(withdrawal.getAddress()); + rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); + rlpOutput.endList(); + }); } public static Bytes encodeOpaqueBytes(final Withdrawal withdrawal) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java index 0bd5cd4ffbb..c7925043f02 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java @@ -58,6 +58,7 @@ void shouldDecodeWithdrawal() { Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); assertThat(withdrawal).isEqualTo(expectedWithdrawal); - assertThat(withdrawal.getRawRlp().get()).isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); + assertThat(withdrawal.getRawRlp().get()) + .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java index e7cc9bbcb48..5893ed7a7ca 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java @@ -20,12 +20,12 @@ import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.ethereum.core.Withdrawal; +import java.util.Optional; + import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; -import java.util.Optional; - class WithdrawalEncoderTest { public static final String WITHDRAWAL_ZERO_CASE = "0xd8808094000000000000000000000000000000000000000080"; @@ -67,11 +67,18 @@ public void shouldEncodeFromRawRlp() { final UInt64 validatorIndex = UInt64.valueOf(2); final Address address = Address.fromHexString("0xffffffff"); final GWei amount = GWei.of(3); - final Withdrawal withdrawal = new Withdrawal(index, validatorIndex, address, amount, Optional.of(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05"))); + final Withdrawal withdrawal = + new Withdrawal( + index, + validatorIndex, + address, + amount, + Optional.of( + Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05"))); final Bytes encoded = WithdrawalEncoder.encodeOpaqueBytes(withdrawal); assertThat(encoded) - .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); + .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } } From 2fb60f865cd9759f21da68208dedc953ef14e77d Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Thu, 12 Dec 2024 10:20:49 +1100 Subject: [PATCH 03/20] 7582: Fix broken test after merge Signed-off-by: Matilda Clerke --- .../besu/ethereum/eth/transactions/PendingTransaction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java index ee5c40a3f4f..4b5e0e8c9b7 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/PendingTransaction.java @@ -421,8 +421,8 @@ public boolean hasPriority() { * class changes its structure. */ public interface MemorySize { - int FRONTIER_AND_ACCESS_LIST_SHALLOW_SIZE = 904; - int EIP1559_AND_EIP4844_SHALLOW_SIZE = 1016; + int FRONTIER_AND_ACCESS_LIST_SHALLOW_SIZE = 912; + int EIP1559_AND_EIP4844_SHALLOW_SIZE = 1024; int OPTIONAL_TO_SIZE = 112; int OPTIONAL_CHAIN_ID_SIZE = 80; int PAYLOAD_SHALLOW_SIZE = 32; From 7738076bbe4f5ec919339a2d29e2d122e1d49983 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Fri, 13 Dec 2024 09:48:07 +1100 Subject: [PATCH 04/20] 7582: Back out withdrawal changes Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/Withdrawal.java | 16 ------------- .../core/encoding/WithdrawalDecoder.java | 17 ++++++-------- .../core/encoding/WithdrawalEncoder.java | 18 +++++---------- .../core/encoding/WithdrawalDecoderTest.java | 2 -- .../core/encoding/WithdrawalEncoderTest.java | 23 ------------------- 5 files changed, 13 insertions(+), 63 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java index ceef9c8b5a5..b82eda72481 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Withdrawal.java @@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput; import java.util.Objects; -import java.util.Optional; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; @@ -33,24 +32,13 @@ public class Withdrawal implements org.hyperledger.besu.plugin.data.Withdrawal { private final UInt64 validatorIndex; private final Address address; private final GWei amount; - private final Optional rawRlp; public Withdrawal( final UInt64 index, final UInt64 validatorIndex, final Address address, final GWei amount) { - this(index, validatorIndex, address, amount, Optional.empty()); - } - - public Withdrawal( - final UInt64 index, - final UInt64 validatorIndex, - final Address address, - final GWei amount, - final Optional rawRlp) { this.index = index; this.validatorIndex = validatorIndex; this.address = address; this.amount = amount; - this.rawRlp = rawRlp; } public static Withdrawal readFrom(final Bytes rlpBytes) { @@ -85,10 +73,6 @@ public GWei getAmount() { return amount; } - public Optional getRawRlp() { - return rawRlp; - } - @Override public String toString() { return "Withdrawal{" diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java index 9079bd7b495..c2e98215b73 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoder.java @@ -20,23 +20,20 @@ import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; -import java.util.Optional; - import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; public class WithdrawalDecoder { public static Withdrawal decode(final RLPInput rlpInput) { - final RLPInput withdrawalRlp = rlpInput.readAsRlp(); - withdrawalRlp.enterList(); - final UInt64 index = UInt64.valueOf(withdrawalRlp.readBigIntegerScalar()); - final UInt64 validatorIndex = UInt64.valueOf(withdrawalRlp.readBigIntegerScalar()); - final Address address = Address.readFrom(withdrawalRlp); - final GWei amount = GWei.of(withdrawalRlp.readUInt64Scalar()); - withdrawalRlp.leaveList(); + rlpInput.enterList(); + final UInt64 index = UInt64.valueOf(rlpInput.readBigIntegerScalar()); + final UInt64 validatorIndex = UInt64.valueOf(rlpInput.readBigIntegerScalar()); + final Address address = Address.readFrom(rlpInput); + final GWei amount = GWei.of(rlpInput.readUInt64Scalar()); + rlpInput.leaveList(); - return new Withdrawal(index, validatorIndex, address, amount, Optional.of(withdrawalRlp.raw())); + return new Withdrawal(index, validatorIndex, address, amount); } public static Withdrawal decodeOpaqueBytes(final Bytes input) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java index 87af3a2fef3..27d6b805cb8 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoder.java @@ -23,18 +23,12 @@ public class WithdrawalEncoder { public static void encode(final Withdrawal withdrawal, final RLPOutput rlpOutput) { - withdrawal - .getRawRlp() - .ifPresentOrElse( - rlpOutput::writeRLPBytes, - () -> { - rlpOutput.startList(); - rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); - rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); - rlpOutput.writeBytes(withdrawal.getAddress()); - rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); - rlpOutput.endList(); - }); + rlpOutput.startList(); + rlpOutput.writeBigIntegerScalar(withdrawal.getIndex().toBigInteger()); + rlpOutput.writeBigIntegerScalar(withdrawal.getValidatorIndex().toBigInteger()); + rlpOutput.writeBytes(withdrawal.getAddress()); + rlpOutput.writeUInt64Scalar(withdrawal.getAmount()); + rlpOutput.endList(); } public static Bytes encodeOpaqueBytes(final Withdrawal withdrawal) { diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java index c7925043f02..9ffd219db0a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalDecoderTest.java @@ -58,7 +58,5 @@ void shouldDecodeWithdrawal() { Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); assertThat(withdrawal).isEqualTo(expectedWithdrawal); - assertThat(withdrawal.getRawRlp().get()) - .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java index 5893ed7a7ca..3e4d81f02be 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/WithdrawalEncoderTest.java @@ -20,8 +20,6 @@ import org.hyperledger.besu.datatypes.GWei; import org.hyperledger.besu.ethereum.core.Withdrawal; -import java.util.Optional; - import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt64; import org.junit.jupiter.api.Test; @@ -60,25 +58,4 @@ void shouldEncode() { assertThat(encoded) .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); } - - @Test - public void shouldEncodeFromRawRlp() { - final UInt64 index = UInt64.valueOf(1); - final UInt64 validatorIndex = UInt64.valueOf(2); - final Address address = Address.fromHexString("0xffffffff"); - final GWei amount = GWei.of(3); - final Withdrawal withdrawal = - new Withdrawal( - index, - validatorIndex, - address, - amount, - Optional.of( - Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05"))); - - final Bytes encoded = WithdrawalEncoder.encodeOpaqueBytes(withdrawal); - - assertThat(encoded) - .isEqualTo(Bytes.fromHexString("0xd803019400000000000000000000000000000000deadbeef05")); - } } From a00bd94abb50800268a6ba593cbd000b6d51fda3 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 7 Jan 2025 16:33:33 +1100 Subject: [PATCH 05/20] 7582: Fix up compile error after merge Signed-off-by: Matilda Clerke --- .../java/org/hyperledger/besu/ethereum/core/BlockHeader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 6a0503827f7..8f3812b8b11 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -246,6 +246,7 @@ public void writeTo(final RLPOutput out) { out.writeBytes(requestsHash); } while (false); out.endList(); + }); } public static BlockHeader readFrom( From 6c0ac42fe71ad122bf53d97bae807f12dbec4727 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Thu, 9 Jan 2025 10:08:05 +1100 Subject: [PATCH 06/20] 7582: Apply naive RLP caching in transaction encoder/decoder classes Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/Transaction.java | 12 ++--- .../AccessListTransactionDecoder.java | 29 ++++++------ .../AccessListTransactionEncoder.java | 44 ++++++++++-------- .../CodeDelegationTransactionDecoder.java | 34 ++++++++------ .../CodeDelegationTransactionEncoder.java | 46 +++++++++++-------- .../encoding/EIP1559TransactionDecoder.java | 31 +++++++------ .../encoding/EIP1559TransactionEncoder.java | 30 +++++++----- .../encoding/FrontierTransactionDecoder.java | 24 +++++----- .../encoding/FrontierTransactionEncoder.java | 24 ++++++---- .../core/encoding/TransactionDecoder.java | 7 ++- .../core/encoding/TransactionEncoder.java | 22 +++++++-- 11 files changed, 177 insertions(+), 126 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index a203c8aa4ae..5fd6fbccaf4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -137,13 +137,7 @@ public static Transaction readFrom(final Bytes rlpBytes) { } public static Transaction readFrom(final RLPInput rlpInput) { - RLPInput transactionRlp = rlpInput.readAsRlp(); - Transaction transaction = - TransactionDecoder.decodeRLP(transactionRlp, EncodingContext.BLOCK_BODY); - return Transaction.builder() - .copiedFrom(transaction) - .rawRlp(Optional.of(transactionRlp.raw())) - .build(); + return TransactionDecoder.decodeRLP(rlpInput, EncodingContext.BLOCK_BODY); } /** @@ -677,6 +671,10 @@ public final Wei getEffectiveGasPrice(final Optional baseFeePerGas) { return getEffectivePriorityFeePerGas(baseFeePerGas).addExact(baseFeePerGas.orElse(Wei.ZERO)); } + public Optional getRawRlp() { + return rawRlp; + } + @Override public TransactionType getType() { return this.transactionType; diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java index b5a06042406..f39c7a6b17d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; +import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -37,21 +38,23 @@ private AccessListTransactionDecoder() { } public static Transaction decode(final RLPInput rlpInput) { - rlpInput.enterList(); + RLPInput transactionRlp = rlpInput.readAsRlp(); + transactionRlp.enterList(); final Transaction.Builder preSignatureTransactionBuilder = Transaction.builder() .type(TransactionType.ACCESS_LIST) - .chainId(BigInteger.valueOf(rlpInput.readLongScalar())) - .nonce(rlpInput.readLongScalar()) - .gasPrice(Wei.of(rlpInput.readUInt256Scalar())) - .gasLimit(rlpInput.readLongScalar()) + .chainId(BigInteger.valueOf(transactionRlp.readLongScalar())) + .nonce(transactionRlp.readLongScalar()) + .gasPrice(Wei.of(transactionRlp.readUInt256Scalar())) + .gasLimit(transactionRlp.readLongScalar()) .to( - rlpInput.readBytes( + transactionRlp.readBytes( addressBytes -> addressBytes.isEmpty() ? null : Address.wrap(addressBytes))) - .value(Wei.of(rlpInput.readUInt256Scalar())) - .payload(rlpInput.readBytes()) + .value(Wei.of(transactionRlp.readUInt256Scalar())) + .payload(transactionRlp.readBytes()) + .rawRlp(Optional.of(transactionRlp.raw())) .accessList( - rlpInput.readList( + transactionRlp.readList( accessListEntryRLPInput -> { accessListEntryRLPInput.enterList(); final AccessListEntry accessListEntry = @@ -61,18 +64,18 @@ public static Transaction decode(final RLPInput rlpInput) { accessListEntryRLPInput.leaveList(); return accessListEntry; })); - final byte recId = (byte) rlpInput.readUnsignedByteScalar(); + final byte recId = (byte) transactionRlp.readUnsignedByteScalar(); final Transaction transaction = preSignatureTransactionBuilder .signature( SIGNATURE_ALGORITHM .get() .createSignature( - rlpInput.readUInt256Scalar().toUnsignedBigInteger(), - rlpInput.readUInt256Scalar().toUnsignedBigInteger(), + transactionRlp.readUInt256Scalar().toUnsignedBigInteger(), + transactionRlp.readUInt256Scalar().toUnsignedBigInteger(), recId)) .build(); - rlpInput.leaveList(); + transactionRlp.leaveList(); return transaction; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java index 54bf8cc41ec..155fedd98fc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java @@ -31,25 +31,31 @@ public class AccessListTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput rlpOutput) { - rlpOutput.startList(); - encodeAccessListInner( - transaction.getChainId(), - transaction.getNonce(), - transaction.getGasPrice().orElseThrow(), - transaction.getGasLimit(), - transaction.getTo(), - transaction.getValue(), - transaction.getPayload(), - transaction - .getAccessList() - .orElseThrow( - () -> - new IllegalStateException( - "Developer error: access list should be guaranteed to be present")), - rlpOutput); - rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); - writeSignature(transaction, rlpOutput); - rlpOutput.endList(); + transaction + .getRawRlp() + .ifPresentOrElse( + rlpOutput::writeRLPBytes, + () -> { + rlpOutput.startList(); + encodeAccessListInner( + transaction.getChainId(), + transaction.getNonce(), + transaction.getGasPrice().orElseThrow(), + transaction.getGasLimit(), + transaction.getTo(), + transaction.getValue(), + transaction.getPayload(), + transaction + .getAccessList() + .orElseThrow( + () -> + new IllegalStateException( + "Developer error: access list should be guaranteed to be present")), + rlpOutput); + rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); + writeSignature(transaction, rlpOutput); + rlpOutput.endList(); + }); } public static void encodeAccessListInner( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java index 88d502f7a18..7613aa11e76 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java @@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; +import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -39,21 +40,23 @@ private CodeDelegationTransactionDecoder() { } public static Transaction decode(final RLPInput input) { - input.enterList(); - final BigInteger chainId = input.readBigIntegerScalar(); + RLPInput transactionRlp = input.readAsRlp(); + transactionRlp.enterList(); + final BigInteger chainId = transactionRlp.readBigIntegerScalar(); final Transaction.Builder builder = Transaction.builder() .type(TransactionType.DELEGATE_CODE) .chainId(chainId) - .nonce(input.readLongScalar()) - .maxPriorityFeePerGas(Wei.of(input.readUInt256Scalar())) - .maxFeePerGas(Wei.of(input.readUInt256Scalar())) - .gasLimit(input.readLongScalar()) - .to(input.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) - .value(Wei.of(input.readUInt256Scalar())) - .payload(input.readBytes()) + .nonce(transactionRlp.readLongScalar()) + .maxPriorityFeePerGas(Wei.of(transactionRlp.readUInt256Scalar())) + .maxFeePerGas(Wei.of(transactionRlp.readUInt256Scalar())) + .gasLimit(transactionRlp.readLongScalar()) + .to(transactionRlp.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) + .value(Wei.of(transactionRlp.readUInt256Scalar())) + .payload(transactionRlp.readBytes()) + .rawRlp(Optional.of(transactionRlp.raw())) .accessList( - input.readList( + transactionRlp.readList( accessListEntryRLPInput -> { accessListEntryRLPInput.enterList(); final AccessListEntry accessListEntry = @@ -63,13 +66,14 @@ public static Transaction decode(final RLPInput input) { accessListEntryRLPInput.leaveList(); return accessListEntry; })) - .codeDelegations(input.readList(CodeDelegationTransactionDecoder::decodeInnerPayload)); + .codeDelegations( + transactionRlp.readList(CodeDelegationTransactionDecoder::decodeInnerPayload)); - final byte recId = (byte) input.readUnsignedByteScalar(); - final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); - final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); + final byte recId = (byte) transactionRlp.readUnsignedByteScalar(); + final BigInteger r = transactionRlp.readUInt256Scalar().toUnsignedBigInteger(); + final BigInteger s = transactionRlp.readUInt256Scalar().toUnsignedBigInteger(); - input.leaveList(); + transactionRlp.leaveList(); return builder.signature(SIGNATURE_ALGORITHM.get().createSignature(r, s, recId)).build(); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java index c34de129251..ccf8153e83d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java @@ -63,25 +63,31 @@ private static void encodeAuthorizationDetails( } public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); - out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeAccessList(out, transaction.getAccessList()); - encodeCodeDelegationInner( - transaction - .getCodeDelegationList() - .orElseThrow( - () -> - new IllegalStateException( - "Developer error: the transaction should be guaranteed to have a code delegation authorizations here")), - out); - writeSignatureAndRecoveryId(transaction, out); - out.endList(); + transaction + .getRawRlp() + .ifPresentOrElse( + out::writeRLPBytes, + () -> { + out.startList(); + out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); + out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeAccessList(out, transaction.getAccessList()); + encodeCodeDelegationInner( + transaction + .getCodeDelegationList() + .orElseThrow( + () -> + new IllegalStateException( + "Developer error: the transaction should be guaranteed to have a code delegation authorizations here")), + out); + writeSignatureAndRecoveryId(transaction, out); + out.endList(); + }); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java index b99f37468e5..43985f1b3c0 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java @@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; +import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -37,21 +38,23 @@ private EIP1559TransactionDecoder() { } public static Transaction decode(final RLPInput input) { - input.enterList(); - final BigInteger chainId = input.readBigIntegerScalar(); + RLPInput transactionRlp = input.readAsRlp(); + transactionRlp.enterList(); + final BigInteger chainId = transactionRlp.readBigIntegerScalar(); final Transaction.Builder builder = Transaction.builder() .type(TransactionType.EIP1559) .chainId(chainId) - .nonce(input.readLongScalar()) - .maxPriorityFeePerGas(Wei.of(input.readUInt256Scalar())) - .maxFeePerGas(Wei.of(input.readUInt256Scalar())) - .gasLimit(input.readLongScalar()) - .to(input.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) - .value(Wei.of(input.readUInt256Scalar())) - .payload(input.readBytes()) + .nonce(transactionRlp.readLongScalar()) + .maxPriorityFeePerGas(Wei.of(transactionRlp.readUInt256Scalar())) + .maxFeePerGas(Wei.of(transactionRlp.readUInt256Scalar())) + .gasLimit(transactionRlp.readLongScalar()) + .to(transactionRlp.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) + .value(Wei.of(transactionRlp.readUInt256Scalar())) + .payload(transactionRlp.readBytes()) + .rawRlp(Optional.of(transactionRlp.raw())) .accessList( - input.readList( + transactionRlp.readList( accessListEntryRLPInput -> { accessListEntryRLPInput.enterList(); final AccessListEntry accessListEntry = @@ -61,18 +64,18 @@ public static Transaction decode(final RLPInput input) { accessListEntryRLPInput.leaveList(); return accessListEntry; })); - final byte recId = (byte) input.readUnsignedByteScalar(); + final byte recId = (byte) transactionRlp.readUnsignedByteScalar(); final Transaction transaction = builder .signature( SIGNATURE_ALGORITHM .get() .createSignature( - input.readUInt256Scalar().toUnsignedBigInteger(), - input.readUInt256Scalar().toUnsignedBigInteger(), + transactionRlp.readUInt256Scalar().toUnsignedBigInteger(), + transactionRlp.readUInt256Scalar().toUnsignedBigInteger(), recId)) .build(); - input.leaveList(); + transactionRlp.leaveList(); return transaction; } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java index bc8e41da820..ef8e8f5b77c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java @@ -25,17 +25,23 @@ public class EIP1559TransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); - out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeAccessList(out, transaction.getAccessList()); - writeSignatureAndRecoveryId(transaction, out); - out.endList(); + transaction + .getRawRlp() + .ifPresentOrElse( + out::writeRLPBytes, + () -> { + out.startList(); + out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); + out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeAccessList(out, transaction.getAccessList()); + writeSignatureAndRecoveryId(transaction, out); + out.endList(); + }); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java index e218eb0ac4d..c63bec41142 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java @@ -41,18 +41,20 @@ public class FrontierTransactionDecoder { Suppliers.memoize(SignatureAlgorithmFactory::getInstance); public static Transaction decode(final RLPInput input) { - input.enterList(); + RLPInput transactionRlp = input.readAsRlp(); + transactionRlp.enterList(); final Transaction.Builder builder = Transaction.builder() .type(TransactionType.FRONTIER) - .nonce(input.readLongScalar()) - .gasPrice(Wei.of(input.readUInt256Scalar())) - .gasLimit(input.readLongScalar()) - .to(input.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) - .value(Wei.of(input.readUInt256Scalar())) - .payload(input.readBytes()); + .nonce(transactionRlp.readLongScalar()) + .gasPrice(Wei.of(transactionRlp.readUInt256Scalar())) + .gasLimit(transactionRlp.readLongScalar()) + .to(transactionRlp.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) + .value(Wei.of(transactionRlp.readUInt256Scalar())) + .payload(transactionRlp.readBytes()) + .rawRlp(Optional.of(transactionRlp.raw())); - final BigInteger v = input.readBigIntegerScalar(); + final BigInteger v = transactionRlp.readBigIntegerScalar(); final byte recId; Optional chainId = Optional.empty(); if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) { @@ -64,11 +66,11 @@ public static Transaction decode(final RLPInput input) { throw new RuntimeException( String.format("An unsupported encoded `v` value of %s was found", v)); } - final BigInteger r = input.readUInt256Scalar().toUnsignedBigInteger(); - final BigInteger s = input.readUInt256Scalar().toUnsignedBigInteger(); + final BigInteger r = transactionRlp.readUInt256Scalar().toUnsignedBigInteger(); + final BigInteger s = transactionRlp.readUInt256Scalar().toUnsignedBigInteger(); final SECPSignature signature = SIGNATURE_ALGORITHM.get().createSignature(r, s, recId); - input.leaveList(); + transactionRlp.leaveList(); chainId.ifPresent(builder::chainId); return builder.signature(signature).build(); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java index 039c3871040..ee15488ade0 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java @@ -23,14 +23,20 @@ public class FrontierTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeSignatureAndV(transaction, out); - out.endList(); + transaction + .getRawRlp() + .ifPresentOrElse( + out::writeRLPBytes, + () -> { + out.startList(); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeSignatureAndV(transaction, out); + out.endList(); + }); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java index 7261aecbeac..f0eaa7eb321 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java @@ -79,7 +79,12 @@ private static Transaction decodeTypedTransaction( TransactionType transactionType = getTransactionType(typedTransactionBytes) .orElseThrow((() -> new IllegalArgumentException("Unsupported transaction type"))); - return decodeTypedTransaction(typedTransactionBytes, transactionType, context); + Transaction typedTransaction = + decodeTypedTransaction(typedTransactionBytes, transactionType, context); + return Transaction.builder() + .copiedFrom(typedTransaction) + .rawRlp(Optional.of(typedTransactionBytes)) + .build(); } /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java index a97f24cbd04..72d86efa8fd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java @@ -57,9 +57,15 @@ public static void encodeRLP( final Transaction transaction, final RLPOutput rlpOutput, final EncodingContext encodingContext) { - final TransactionType transactionType = getTransactionType(transaction); - Bytes opaqueBytes = encodeOpaqueBytes(transaction, encodingContext); - encodeRLP(transactionType, opaqueBytes, rlpOutput); + transaction + .getRawRlp() + .ifPresentOrElse( + rlpOutput::writeRLPBytes, + () -> { + final TransactionType transactionType = getTransactionType(transaction); + Bytes opaqueBytes = encodeOpaqueBytes(transaction, encodingContext); + encodeRLP(transactionType, opaqueBytes, rlpOutput); + }); } /** @@ -94,8 +100,14 @@ public static Bytes encodeOpaqueBytes( } else { final Encoder encoder = getEncoder(transactionType, encodingContext); final BytesValueRLPOutput out = new BytesValueRLPOutput(); - out.writeByte(transaction.getType().getSerializedType()); - encoder.encode(transaction, out); + transaction + .getRawRlp() + .ifPresentOrElse( + out::writeRLPBytes, + () -> { + out.writeByte(transaction.getType().getSerializedType()); + encoder.encode(transaction, out); + }); return out.encoded(); } } From 981a1e7c9c750c814b470e0e8e37decf37f85db6 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 21 Jan 2025 08:40:00 +1100 Subject: [PATCH 07/20] 8053: Add RLPDecodingHelpers.Kind.EM and handle empty lists in AbstractRLPInput Signed-off-by: Matilda Clerke --- .../hyperledger/besu/ethereum/rlp/AbstractRLPInput.java | 5 +++++ .../hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java | 5 +++++ .../java/org/hyperledger/besu/ethereum/rlp/RLPTest.java | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index 51a7f87e12e..bcfb4a4af9e 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -490,6 +490,7 @@ public int enterList(final boolean skipCount) { if (depth > endOfListOffset.length) { endOfListOffset = Arrays.copyOf(endOfListOffset, (endOfListOffset.length * 3) / 2); } + // The first list element is the beginning of the payload. Its end is the end of this item. final long listStart = currentPayloadOffset; final long listEnd = nextItem(); @@ -519,6 +520,10 @@ public int enterList(final boolean skipCount) { } } + if (currentKind != RLPDecodingHelpers.Kind.EMPTY_LIST) { + depth--; + } + // And lastly reset on the list first element before returning setTo(listStart); return count; diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java index f53931ba67c..946a4babf5d 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java @@ -28,6 +28,7 @@ enum Kind { BYTE_ELEMENT, SHORT_ELEMENT, LONG_ELEMENT, + EMPTY_LIST, SHORT_LIST, LONG_LIST; @@ -38,6 +39,8 @@ static Kind of(final int prefix) { return Kind.SHORT_ELEMENT; } else if (prefix <= 0xbf) { return Kind.LONG_ELEMENT; + } else if (prefix == 0xc0) { + return Kind.EMPTY_LIST; } else if (prefix <= 0xf7) { return Kind.SHORT_LIST; } else { @@ -47,6 +50,7 @@ static Kind of(final int prefix) { boolean isList() { switch (this) { + case EMPTY_LIST: case SHORT_LIST: case LONG_LIST: return true; @@ -121,6 +125,7 @@ static RLPElementMetadata rlpElementMetadata( payloadStart = elementStart + 1 + sizeLengthElt; payloadSize = readLongSize(byteGetter, size, elementStart, sizeLengthElt); break; + case EMPTY_LIST: case SHORT_LIST: payloadStart = elementStart + 1; payloadSize = prefix - 0xc0; diff --git a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java index a4389cafa98..98fa34721f6 100644 --- a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java +++ b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java @@ -168,6 +168,14 @@ public void calculateSize_overflowMaxRLPStringLength() { .hasMessageContaining("RLP item exceeds max supported size of 2147483647: 2147483648"); } + @Test + public void testValidateWithEmptyListIncluded() { + Bytes validRlp = + Bytes.fromHexString( + "01f90126018828da1b7df09b04b484e4aed78d880d84a24f16cbf30394d5d9bef76808f3b572e5900112b81927ba5bb5f6a0a99de4ef3bc2b17c8137ad659878f9e93df1f658367aca286452474b9ef3765ea073d51abbd89cb8196f0efb6892f94d68fccc2c35f0b84609e5f12c55dd85aba8f872d69473724dddfb04b01dcceb0c8aead641c58dad5695c0f8599481baeea87c10d40a47902028e61cfdc243d9d160f842a008aabc9fb77cc723a56017e14f1ce8b1698341734a6823ce02043e016b544901a0214a2ddab82fec85c0b9fe0549c475be5b887bb4b8995b24fb5c6846f88b527b01a02c2051ba70ca2d5088c790c065d288f187a06ffb498c6e3b488873c9bf04fbb2a061bac48599e7941469a549570b12c3d997f309386bb0a2594bd28cca706fc6fb"); + RLP.validate(validRlp); + } + private static Bytes h(final String hex) { return Bytes.fromHexString(hex); } From 85b0d4a5dc0902e777e4bf9901058cbfb0e832d8 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 21 Jan 2025 08:46:31 +1100 Subject: [PATCH 08/20] 7582: Add trace logging to AbstractRLPInput Signed-off-by: Matilda Clerke --- .../besu/ethereum/rlp/AbstractRLPInput.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index 51a7f87e12e..29b1bf362f1 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -29,9 +29,11 @@ import org.apache.tuweni.bytes.MutableBytes32; import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; abstract class AbstractRLPInput implements RLPInput { - + private static final Logger LOG = LoggerFactory.getLogger(AbstractRLPInput.class); private static final String errorMessageSuffix = " (at bytes %d-%d: %s%s[%s]%s%s)"; private final boolean lenient; @@ -290,9 +292,11 @@ public void skipNext() { @Override public long readLongScalar() { + LOG.trace("Reading long scalar, currentItem = {}", currentItem); checkScalar("long scalar", 8); long res = readGenericLongScalar(); setTo(nextItem()); + LOG.trace("Read long scalar, {}, currentItem = {}", res, currentItem); return res; } @@ -327,9 +331,11 @@ public long readUnsignedIntScalar() { @Override public int readUnsignedByteScalar() { + LOG.trace("Reading unsigned byte scalar, currentItem = {}", currentItem); checkScalar("unsigned byte scalar", 1); int result = (currentPayloadSize == 0) ? 0 : payloadByte(0) & 0xff; setTo(nextItem()); + LOG.trace("Read unsigned byte scalar {}, currentItem = {}", result, currentItem); return result; } @@ -355,16 +361,21 @@ public UInt64 readUInt64Scalar() { } private Bytes32 readBytes32Scalar() { + LOG.trace("Reading 32-bytes scalar"); checkScalar("32-bytes scalar", 32); final MutableBytes32 res = MutableBytes32.create(); payloadSlice().copyTo(res, res.size() - currentPayloadSize); setTo(nextItem()); + LOG.trace("Read 32-bytes scalar {}", res); return res; } @Override public UInt256 readUInt256Scalar() { - return UInt256.fromBytes(readBytes32Scalar()); + LOG.trace("Reading UInt256 scalar, currentItem = {}", currentItem); + UInt256 res = UInt256.fromBytes(readBytes32Scalar()); + LOG.trace("Read UInt256 scalar {}, currentItem = {}", res, currentItem); + return res; } @Override @@ -422,17 +433,21 @@ public InetAddress readInetAddress() { @Override public Bytes readBytes() { + LOG.trace("Reading arbitrary bytes, currentItem = {}", currentItem); checkElt("arbitrary bytes value"); final Bytes res = payloadSlice(); setTo(nextItem()); + LOG.trace("Read arbitrary bytes {}, currentItem = {}", res, currentItem); return res; } @Override public Bytes32 readBytes32() { + LOG.trace("Reading Bytes32, currentItem = {}", currentItem); checkElt("32 bytes value", 32); final Bytes32 res = inputSlice32(currentPayloadOffset); setTo(nextItem()); + LOG.trace("Read Bytes32 {}, currentItem = {}", res, currentItem); return res; } @@ -479,6 +494,7 @@ public int enterList() { * @return -1 if skipCount==true, otherwise, the number of item of the entered list. */ public int enterList(final boolean skipCount) { + LOG.trace("Entering list (depth = {}, endOfListOffset = {}, currentItem = {})", depth, endOfListOffset, currentItem); if (currentItem >= size) { throw error("Cannot enter a lists, input is fully consumed"); } @@ -521,6 +537,7 @@ public int enterList(final boolean skipCount) { // And lastly reset on the list first element before returning setTo(listStart); + LOG.trace("Entered list (depth = {}, endOfListOffset = {}, currentItem = {}, listEnd = {}, elements = {})", depth, endOfListOffset, currentItem, listEnd, count); return count; } @@ -535,6 +552,7 @@ public void leaveListLenient() { } private void leaveList(final boolean ignoreRest) { + LOG.trace("Leaving list (depth = {}, endOfListOffset = {}, ignoreRest = {}, currentItem = {}", depth, endOfListOffset, ignoreRest, currentItem); checkState(depth > 0, "Not within an RLP list"); if (!ignoreRest) { @@ -543,6 +561,7 @@ private void leaveList(final boolean ignoreRest) { } --depth; + LOG.trace("Left list (depth = {}, endOfListOffset = {}, ignoreRes = {}, currentItem = {}", depth, endOfListOffset, ignoreRest, currentItem); } @Override From a9121b31723a3f75d044fdc7e5302615b584678a Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 21 Jan 2025 14:04:52 +1100 Subject: [PATCH 09/20] Revert previous change, implement new fix Signed-off-by: Matilda Clerke --- .../org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java | 4 ---- .../src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java | 5 +++-- .../hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java | 5 ----- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index bcfb4a4af9e..be37c102aec 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -520,10 +520,6 @@ public int enterList(final boolean skipCount) { } } - if (currentKind != RLPDecodingHelpers.Kind.EMPTY_LIST) { - depth--; - } - // And lastly reset on the list first element before returning setTo(listStart); return count; diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java index bdd07bf0fbb..b3c18749ddb 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java @@ -187,10 +187,11 @@ public static Bytes decodeOne(final Bytes encodedValue) { public static void validate(final Bytes encodedValue) { final RLPInput in = input(encodedValue); while (!in.isDone()) { + while (in.isEndOfCurrentList()) { + in.leaveList(); + } if (in.nextIsList()) { in.enterList(); - } else if (in.isEndOfCurrentList()) { - in.leaveList(); } else { // Skip does as much validation as can be done in general, without allocating anything. in.skipNext(); diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java index 946a4babf5d..f53931ba67c 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java @@ -28,7 +28,6 @@ enum Kind { BYTE_ELEMENT, SHORT_ELEMENT, LONG_ELEMENT, - EMPTY_LIST, SHORT_LIST, LONG_LIST; @@ -39,8 +38,6 @@ static Kind of(final int prefix) { return Kind.SHORT_ELEMENT; } else if (prefix <= 0xbf) { return Kind.LONG_ELEMENT; - } else if (prefix == 0xc0) { - return Kind.EMPTY_LIST; } else if (prefix <= 0xf7) { return Kind.SHORT_LIST; } else { @@ -50,7 +47,6 @@ static Kind of(final int prefix) { boolean isList() { switch (this) { - case EMPTY_LIST: case SHORT_LIST: case LONG_LIST: return true; @@ -125,7 +121,6 @@ static RLPElementMetadata rlpElementMetadata( payloadStart = elementStart + 1 + sizeLengthElt; payloadSize = readLongSize(byteGetter, size, elementStart, sizeLengthElt); break; - case EMPTY_LIST: case SHORT_LIST: payloadStart = elementStart + 1; payloadSize = prefix - 0xc0; From e5652881806b80bc8dca4b244b5994f85bb9374d Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 21 Jan 2025 14:19:26 +1100 Subject: [PATCH 10/20] Revert previous change, implement new fix Signed-off-by: Matilda Clerke --- .../java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java | 1 - 1 file changed, 1 deletion(-) diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index be37c102aec..51a7f87e12e 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -490,7 +490,6 @@ public int enterList(final boolean skipCount) { if (depth > endOfListOffset.length) { endOfListOffset = Arrays.copyOf(endOfListOffset, (endOfListOffset.length * 3) / 2); } - // The first list element is the beginning of the payload. Its end is the end of this item. final long listStart = currentPayloadOffset; final long listEnd = nextItem(); From cb03e27b5df2f5d0ff498eed2ef4a16d728541d7 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 21 Jan 2025 16:17:38 +1100 Subject: [PATCH 11/20] 7582: Finish applying naive RLP caching to transaction encoder/decoder classes Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/Transaction.java | 4 +-- .../AccessListTransactionEncoder.java | 9 ++++-- .../CodeDelegationTransactionEncoder.java | 4 ++- .../encoding/EIP1559TransactionEncoder.java | 4 ++- .../core/encoding/TransactionDecoder.java | 7 +---- .../core/encoding/TransactionEncoder.java | 17 +++++------ .../encoding/TransactionRLPDecoderTest.java | 19 ++++++++++++ ethereum/rlp/build.gradle | 3 +- .../besu/ethereum/rlp/AbstractRLPInput.java | 28 +++++++++++++++--- .../besu/ethereum/rlp/AbstractRLPOutput.java | 29 +++++++++++++++++++ 10 files changed, 95 insertions(+), 29 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index f990537e6d7..82567d25f7a 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -489,9 +489,7 @@ private Bytes32 getOrComputeSenderRecoveryHash() { * @param out the output to write the transaction to */ public void writeTo(final RLPOutput out) { - rawRlp.ifPresentOrElse( - out::writeRLPBytes, - () -> TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY)); + TransactionEncoder.encodeRLP(this, out, EncodingContext.BLOCK_BODY); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java index 155fedd98fc..9b70d55ec13 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java @@ -34,7 +34,9 @@ public static void encode(final Transaction transaction, final RLPOutput rlpOutp transaction .getRawRlp() .ifPresentOrElse( - rlpOutput::writeRLPBytes, + (rawRlp) -> + rlpOutput.writeRLPBytes( + Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), () -> { rlpOutput.startList(); encodeAccessListInner( @@ -106,8 +108,9 @@ public static void writeAccessList( out.writeBytes(accessListEntry.address()); out.writeList( accessListEntry.storageKeys(), - (storageKeyBytes, storageKeyBytesRLPOutput) -> - storageKeyBytesRLPOutput.writeBytes(storageKeyBytes)); + (storageKeyBytes, storageKeyBytesRLPOutput) -> { + storageKeyBytesRLPOutput.writeBytes(storageKeyBytes); + }); accessListEntryRLPOutput.endList(); }); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java index ccf8153e83d..6789ccdc669 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java @@ -66,7 +66,9 @@ public static void encode(final Transaction transaction, final RLPOutput out) { transaction .getRawRlp() .ifPresentOrElse( - out::writeRLPBytes, + (rawRlp) -> + out.writeRLPBytes( + Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), () -> { out.startList(); out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java index ef8e8f5b77c..421f72c7a37 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java @@ -28,7 +28,9 @@ public static void encode(final Transaction transaction, final RLPOutput out) { transaction .getRawRlp() .ifPresentOrElse( - out::writeRLPBytes, + (rawRlp) -> + out.writeRLPBytes( + Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), () -> { out.startList(); out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java index f0eaa7eb321..7261aecbeac 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionDecoder.java @@ -79,12 +79,7 @@ private static Transaction decodeTypedTransaction( TransactionType transactionType = getTransactionType(typedTransactionBytes) .orElseThrow((() -> new IllegalArgumentException("Unsupported transaction type"))); - Transaction typedTransaction = - decodeTypedTransaction(typedTransactionBytes, transactionType, context); - return Transaction.builder() - .copiedFrom(typedTransaction) - .rawRlp(Optional.of(typedTransactionBytes)) - .build(); + return decodeTypedTransaction(typedTransactionBytes, transactionType, context); } /** diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java index 72d86efa8fd..7d2b7b22d6e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java @@ -57,15 +57,10 @@ public static void encodeRLP( final Transaction transaction, final RLPOutput rlpOutput, final EncodingContext encodingContext) { - transaction - .getRawRlp() - .ifPresentOrElse( - rlpOutput::writeRLPBytes, - () -> { - final TransactionType transactionType = getTransactionType(transaction); - Bytes opaqueBytes = encodeOpaqueBytes(transaction, encodingContext); - encodeRLP(transactionType, opaqueBytes, rlpOutput); - }); + final TransactionType transactionType = getTransactionType(transaction); + + Bytes opaqueBytes = encodeOpaqueBytes(transaction, encodingContext); + encodeRLP(transactionType, opaqueBytes, rlpOutput); } /** @@ -103,7 +98,9 @@ public static Bytes encodeOpaqueBytes( transaction .getRawRlp() .ifPresentOrElse( - out::writeRLPBytes, + (rawRlp) -> + out.writeRLPBytes( + Bytes.concatenate(Bytes.of(transactionType.getSerializedType()), rawRlp)), () -> { out.writeByte(transaction.getType().getSerializedType()); encoder.encode(transaction, out); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java index 19f3e5bf7a5..9648a83d105 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java @@ -19,7 +19,9 @@ import static org.hyperledger.besu.evm.account.Account.MAX_NONCE; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.BlockDataGenerator; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPException; @@ -33,8 +35,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class TransactionRLPDecoderTest { + private static final Logger LOG = LoggerFactory.getLogger(TransactionRLPDecoderTest.class); private static final String FRONTIER_TX_RLP = "0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; @@ -79,6 +84,20 @@ void shouldDecodeWithHighNonce() { assertThat(transaction.getNonce()).isEqualTo(MAX_NONCE - 1); } + @Test + void testForAccessListTransaction() { + BlockDataGenerator gen = new BlockDataGenerator(); + Transaction accessListTransaction = gen.transaction(TransactionType.ACCESS_LIST); + Bytes encodedBytes = + TransactionEncoder.encodeOpaqueBytes(accessListTransaction, EncodingContext.BLOCK_BODY); + Transaction decodedTransaction = + TransactionDecoder.decodeOpaqueBytes(encodedBytes, EncodingContext.BLOCK_BODY); + assertThat(accessListTransaction).isEqualTo(decodedTransaction); + Bytes reencodedBytes = + TransactionEncoder.encodeOpaqueBytes(decodedTransaction, EncodingContext.BLOCK_BODY); + assertThat(encodedBytes).isEqualTo(reencodedBytes); + } + private static Collection dataTransactionSize() { return Arrays.asList( new Object[][] { diff --git a/ethereum/rlp/build.gradle b/ethereum/rlp/build.gradle index b95243e2ead..c99dbf2d442 100644 --- a/ethereum/rlp/build.gradle +++ b/ethereum/rlp/build.gradle @@ -30,13 +30,14 @@ jar { } dependencies { + api 'org.slf4j:slf4j-api' + annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess' implementation 'io.tmio:tuweni-bytes' implementation 'io.tmio:tuweni-units' implementation 'com.google.guava:guava' - jmh project(':util') testImplementation project(':testutil') diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index 29b1bf362f1..575613aadb4 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -494,7 +494,11 @@ public int enterList() { * @return -1 if skipCount==true, otherwise, the number of item of the entered list. */ public int enterList(final boolean skipCount) { - LOG.trace("Entering list (depth = {}, endOfListOffset = {}, currentItem = {})", depth, endOfListOffset, currentItem); + LOG.trace( + "Entering list (depth = {}, endOfListOffset = {}, currentItem = {})", + depth, + endOfListOffset, + currentItem); if (currentItem >= size) { throw error("Cannot enter a lists, input is fully consumed"); } @@ -537,7 +541,13 @@ public int enterList(final boolean skipCount) { // And lastly reset on the list first element before returning setTo(listStart); - LOG.trace("Entered list (depth = {}, endOfListOffset = {}, currentItem = {}, listEnd = {}, elements = {})", depth, endOfListOffset, currentItem, listEnd, count); + LOG.trace( + "Entered list (depth = {}, endOfListOffset = {}, currentItem = {}, listEnd = {}, elements = {})", + depth, + endOfListOffset, + currentItem, + listEnd, + count); return count; } @@ -552,7 +562,12 @@ public void leaveListLenient() { } private void leaveList(final boolean ignoreRest) { - LOG.trace("Leaving list (depth = {}, endOfListOffset = {}, ignoreRest = {}, currentItem = {}", depth, endOfListOffset, ignoreRest, currentItem); + LOG.trace( + "Leaving list (depth = {}, endOfListOffset = {}, ignoreRest = {}, currentItem = {}", + depth, + endOfListOffset, + ignoreRest, + currentItem); checkState(depth > 0, "Not within an RLP list"); if (!ignoreRest) { @@ -561,7 +576,12 @@ private void leaveList(final boolean ignoreRest) { } --depth; - LOG.trace("Left list (depth = {}, endOfListOffset = {}, ignoreRes = {}, currentItem = {}", depth, endOfListOffset, ignoreRest, currentItem); + LOG.trace( + "Left list (depth = {}, endOfListOffset = {}, ignoreRes = {}, currentItem = {}", + depth, + endOfListOffset, + ignoreRest, + currentItem); } @Override diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java index 73eebbb212e..0f711dc3d69 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java @@ -23,8 +23,11 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.MutableBytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; abstract class AbstractRLPOutput implements RLPOutput { + private static final Logger LOG = LoggerFactory.getLogger(AbstractRLPOutput.class); /* * The algorithm implemented works as follows: * @@ -79,10 +82,12 @@ private int currentList() { @Override public void writeBytes(final Bytes v) { + LOG.trace("Writing bytes {}", v); checkState( stackSize > 1 || values.isEmpty(), "Terminated RLP output, cannot add more elements"); values.add(v); payloadSizes[currentList()] += RLPEncodingHelpers.elementSize(v); + LOG.trace("Wrote bytes {}", v); } @Override @@ -97,6 +102,12 @@ public void writeRaw(final Bytes v) { @Override public void startList() { + LOG.trace( + "Starting list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", + stackSize, + listsCount, + payloadSizes, + parentListStack); values.add(LIST_MARKER); ++listsCount; // we'll add a new element to payloadSizes ++stackSize; // and to the list stack. @@ -112,10 +123,22 @@ public void startList() { // The new current list size is store in the slot we just made room for by incrementing // listsCount parentListStack[stackSize - 1] = listsCount - 1; + LOG.trace( + "Started list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", + stackSize, + listsCount, + payloadSizes, + parentListStack); } @Override public void endList() { + LOG.trace( + "Ending list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", + stackSize, + listsCount, + payloadSizes, + parentListStack); checkState(stackSize > 1, "LeaveList() called with no prior matching startList()"); final int current = currentList(); @@ -125,6 +148,12 @@ public void endList() { // We just finished an item of our parent list, add it to that parent list size now. final int newCurrent = currentList(); payloadSizes[newCurrent] += finishedListSize; + LOG.trace( + "Ended list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", + stackSize, + listsCount, + payloadSizes, + parentListStack); } /** From 3cddf4830bd6b8438618c016898d95064eb6ea95 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 22 Jan 2025 07:59:30 +1100 Subject: [PATCH 12/20] Remove unused LOG Signed-off-by: Matilda Clerke --- .../besu/ethereum/core/encoding/TransactionRLPDecoderTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java index 9648a83d105..ba0b5d8e6b0 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/core/encoding/TransactionRLPDecoderTest.java @@ -35,11 +35,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; class TransactionRLPDecoderTest { - private static final Logger LOG = LoggerFactory.getLogger(TransactionRLPDecoderTest.class); private static final String FRONTIER_TX_RLP = "0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; From 5ba365b3349896e539276601868e83536565afce Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 22 Jan 2025 08:48:24 +1100 Subject: [PATCH 13/20] 7582: Make explicit the expectation that RLP.validate does not throw an exception in test Signed-off-by: Matilda Clerke --- .../test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java index 144e17c55ee..2809484e6c6 100644 --- a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java +++ b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java @@ -17,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import org.assertj.core.api.Assertions; import org.hyperledger.besu.ethereum.rlp.util.RLPTestUtil; import java.util.Random; @@ -176,7 +177,7 @@ public void testValidateWithListEndingAtStartOfList() { // ["0x02"] // ] Bytes validRlp = Bytes.fromHexString("c4c101c102"); - RLP.validate(validRlp); + Assertions.assertThatCode(() -> RLP.validate(validRlp)).doesNotThrowAnyException(); } private static Bytes h(final String hex) { From 90e60c28b848438c0e217a0eb5369ea9883316f7 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 22 Jan 2025 09:04:04 +1100 Subject: [PATCH 14/20] 7582: SPOTLESS Signed-off-by: Matilda Clerke --- .../test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java index 2809484e6c6..fb885233ccc 100644 --- a/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java +++ b/ethereum/rlp/src/test/java/org/hyperledger/besu/ethereum/rlp/RLPTest.java @@ -17,12 +17,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -import org.assertj.core.api.Assertions; import org.hyperledger.besu.ethereum.rlp.util.RLPTestUtil; import java.util.Random; import org.apache.tuweni.bytes.Bytes; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; public class RLPTest { From 1d090fd60b58a831d0d03e99f6427d4d91b3b8af Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 28 Jan 2025 09:51:03 +1100 Subject: [PATCH 15/20] 7582: Remove redundant curly braces Signed-off-by: Matilda Clerke --- .../ethereum/core/encoding/AccessListTransactionEncoder.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java index 9b70d55ec13..9d90b7fc7cd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java @@ -108,9 +108,8 @@ public static void writeAccessList( out.writeBytes(accessListEntry.address()); out.writeList( accessListEntry.storageKeys(), - (storageKeyBytes, storageKeyBytesRLPOutput) -> { - storageKeyBytesRLPOutput.writeBytes(storageKeyBytes); - }); + (storageKeyBytes, storageKeyBytesRLPOutput) -> + storageKeyBytesRLPOutput.writeBytes(storageKeyBytes)); accessListEntryRLPOutput.endList(); }); } From 8b1c90175aaa7e2c188f645fd017c11726baa029 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 28 Jan 2025 10:04:09 +1100 Subject: [PATCH 16/20] 7582: Remove Optional from rawRlp in Transaction.Builder Signed-off-by: Matilda Clerke --- .../org/hyperledger/besu/ethereum/core/Transaction.java | 6 +++--- .../core/encoding/AccessListTransactionDecoder.java | 3 +-- .../core/encoding/CodeDelegationTransactionDecoder.java | 3 +-- .../ethereum/core/encoding/EIP1559TransactionDecoder.java | 3 +-- .../ethereum/core/encoding/FrontierTransactionDecoder.java | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java index 82567d25f7a..f5efe7d9284 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java @@ -1203,7 +1203,7 @@ public static class Builder { protected List versionedHashes = null; private BlobsWithCommitments blobsWithCommitments; protected Optional> codeDelegationAuthorizations = Optional.empty(); - protected Optional rawRlp = Optional.empty(); + protected Bytes rawRlp = null; public Builder copiedFrom(final Transaction toCopy) { this.transactionType = toCopy.transactionType; @@ -1309,7 +1309,7 @@ public Builder versionedHashes(final List versionedHashes) { return this; } - public Builder rawRlp(final Optional rawRlp) { + public Builder rawRlp(final Bytes rawRlp) { this.rawRlp = rawRlp; return this; } @@ -1354,7 +1354,7 @@ public Transaction build() { Optional.ofNullable(versionedHashes), Optional.ofNullable(blobsWithCommitments), codeDelegationAuthorizations, - rawRlp); + Optional.ofNullable(rawRlp)); } public Transaction signAndBuild(final KeyPair keys) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java index f39c7a6b17d..9474b784d81 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionDecoder.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; -import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -52,7 +51,7 @@ public static Transaction decode(final RLPInput rlpInput) { addressBytes -> addressBytes.isEmpty() ? null : Address.wrap(addressBytes))) .value(Wei.of(transactionRlp.readUInt256Scalar())) .payload(transactionRlp.readBytes()) - .rawRlp(Optional.of(transactionRlp.raw())) + .rawRlp(transactionRlp.raw()) .accessList( transactionRlp.readList( accessListEntryRLPInput -> { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java index 7613aa11e76..f658b5e4dd4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionDecoder.java @@ -26,7 +26,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; -import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -54,7 +53,7 @@ public static Transaction decode(final RLPInput input) { .to(transactionRlp.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) .value(Wei.of(transactionRlp.readUInt256Scalar())) .payload(transactionRlp.readBytes()) - .rawRlp(Optional.of(transactionRlp.raw())) + .rawRlp(transactionRlp.raw()) .accessList( transactionRlp.readList( accessListEntryRLPInput -> { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java index 43985f1b3c0..ba8e81e7d2d 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionDecoder.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput; import java.math.BigInteger; -import java.util.Optional; import java.util.function.Supplier; import com.google.common.base.Suppliers; @@ -52,7 +51,7 @@ public static Transaction decode(final RLPInput input) { .to(transactionRlp.readBytes(v -> v.isEmpty() ? null : Address.wrap(v))) .value(Wei.of(transactionRlp.readUInt256Scalar())) .payload(transactionRlp.readBytes()) - .rawRlp(Optional.of(transactionRlp.raw())) + .rawRlp(transactionRlp.raw()) .accessList( transactionRlp.readList( accessListEntryRLPInput -> { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java index c63bec41142..641caff3e0f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionDecoder.java @@ -52,7 +52,7 @@ public static Transaction decode(final RLPInput input) { .to(transactionRlp.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) .value(Wei.of(transactionRlp.readUInt256Scalar())) .payload(transactionRlp.readBytes()) - .rawRlp(Optional.of(transactionRlp.raw())); + .rawRlp(transactionRlp.raw()); final BigInteger v = transactionRlp.readBigIntegerScalar(); final byte recId; From 4f6645e91f32f1b81bf93107704c4a43426f5f54 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Tue, 28 Jan 2025 10:28:34 +1100 Subject: [PATCH 17/20] 7582: Make new BlockHeader constructor private Signed-off-by: Matilda Clerke --- .../java/org/hyperledger/besu/ethereum/core/BlockHeader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 8f3812b8b11..0eff53c4e11 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -95,7 +95,7 @@ public BlockHeader( Optional.empty()); } - public BlockHeader( + private BlockHeader( final Hash parentHash, final Hash ommersHash, final Address coinbase, From 4f75e4e42c0211db99c0dac586c7bbb621db5b30 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 29 Jan 2025 09:38:38 +1100 Subject: [PATCH 18/20] Refactor tranaction encoder classes Signed-off-by: Matilda Clerke --- .../core/encoding/AccessListTransactionEncoder.java | 8 -------- .../core/encoding/CodeDelegationTransactionEncoder.java | 8 -------- .../ethereum/core/encoding/EIP1559TransactionEncoder.java | 8 -------- .../core/encoding/FrontierTransactionEncoder.java | 6 ------ 4 files changed, 30 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java index 9d90b7fc7cd..4ed9566197e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java @@ -31,13 +31,6 @@ public class AccessListTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput rlpOutput) { - transaction - .getRawRlp() - .ifPresentOrElse( - (rawRlp) -> - rlpOutput.writeRLPBytes( - Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), - () -> { rlpOutput.startList(); encodeAccessListInner( transaction.getChainId(), @@ -57,7 +50,6 @@ public static void encode(final Transaction transaction, final RLPOutput rlpOutp rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); writeSignature(transaction, rlpOutput); rlpOutput.endList(); - }); } public static void encodeAccessListInner( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java index 6789ccdc669..1ca23eaa2c9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java @@ -63,13 +63,6 @@ private static void encodeAuthorizationDetails( } public static void encode(final Transaction transaction, final RLPOutput out) { - transaction - .getRawRlp() - .ifPresentOrElse( - (rawRlp) -> - out.writeRLPBytes( - Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), - () -> { out.startList(); out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); out.writeLongScalar(transaction.getNonce()); @@ -90,6 +83,5 @@ public static void encode(final Transaction transaction, final RLPOutput out) { out); writeSignatureAndRecoveryId(transaction, out); out.endList(); - }); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java index 421f72c7a37..d4438e0ede9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java @@ -25,13 +25,6 @@ public class EIP1559TransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - transaction - .getRawRlp() - .ifPresentOrElse( - (rawRlp) -> - out.writeRLPBytes( - Bytes.concatenate(Bytes.of(transaction.getType().getSerializedType()), rawRlp)), - () -> { out.startList(); out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); out.writeLongScalar(transaction.getNonce()); @@ -44,6 +37,5 @@ public static void encode(final Transaction transaction, final RLPOutput out) { writeAccessList(out, transaction.getAccessList()); writeSignatureAndRecoveryId(transaction, out); out.endList(); - }); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java index ee15488ade0..1703a1c61c0 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java @@ -23,11 +23,6 @@ public class FrontierTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - transaction - .getRawRlp() - .ifPresentOrElse( - out::writeRLPBytes, - () -> { out.startList(); out.writeLongScalar(transaction.getNonce()); out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); @@ -37,6 +32,5 @@ public static void encode(final Transaction transaction, final RLPOutput out) { out.writeBytes(transaction.getPayload()); writeSignatureAndV(transaction, out); out.endList(); - }); } } From 29876271f896644dbe1018654b5bb4d84afffaab Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 29 Jan 2025 09:44:37 +1100 Subject: [PATCH 19/20] Remove logging changes from RLP module Signed-off-by: Matilda Clerke --- ethereum/rlp/build.gradle | 2 - .../besu/ethereum/rlp/AbstractRLPInput.java | 42 +------------------ .../besu/ethereum/rlp/AbstractRLPOutput.java | 29 ------------- 3 files changed, 1 insertion(+), 72 deletions(-) diff --git a/ethereum/rlp/build.gradle b/ethereum/rlp/build.gradle index c99dbf2d442..7756e1bafa9 100644 --- a/ethereum/rlp/build.gradle +++ b/ethereum/rlp/build.gradle @@ -30,8 +30,6 @@ jar { } dependencies { - api 'org.slf4j:slf4j-api' - annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess' implementation 'io.tmio:tuweni-bytes' diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java index 575613aadb4..5ca695ef582 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -29,11 +29,8 @@ import org.apache.tuweni.bytes.MutableBytes32; import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt64; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; abstract class AbstractRLPInput implements RLPInput { - private static final Logger LOG = LoggerFactory.getLogger(AbstractRLPInput.class); private static final String errorMessageSuffix = " (at bytes %d-%d: %s%s[%s]%s%s)"; private final boolean lenient; @@ -292,11 +289,9 @@ public void skipNext() { @Override public long readLongScalar() { - LOG.trace("Reading long scalar, currentItem = {}", currentItem); checkScalar("long scalar", 8); long res = readGenericLongScalar(); setTo(nextItem()); - LOG.trace("Read long scalar, {}, currentItem = {}", res, currentItem); return res; } @@ -331,11 +326,9 @@ public long readUnsignedIntScalar() { @Override public int readUnsignedByteScalar() { - LOG.trace("Reading unsigned byte scalar, currentItem = {}", currentItem); checkScalar("unsigned byte scalar", 1); int result = (currentPayloadSize == 0) ? 0 : payloadByte(0) & 0xff; setTo(nextItem()); - LOG.trace("Read unsigned byte scalar {}, currentItem = {}", result, currentItem); return result; } @@ -361,21 +354,16 @@ public UInt64 readUInt64Scalar() { } private Bytes32 readBytes32Scalar() { - LOG.trace("Reading 32-bytes scalar"); checkScalar("32-bytes scalar", 32); final MutableBytes32 res = MutableBytes32.create(); payloadSlice().copyTo(res, res.size() - currentPayloadSize); setTo(nextItem()); - LOG.trace("Read 32-bytes scalar {}", res); return res; } @Override public UInt256 readUInt256Scalar() { - LOG.trace("Reading UInt256 scalar, currentItem = {}", currentItem); - UInt256 res = UInt256.fromBytes(readBytes32Scalar()); - LOG.trace("Read UInt256 scalar {}, currentItem = {}", res, currentItem); - return res; + return UInt256.fromBytes(readBytes32Scalar()); } @Override @@ -433,21 +421,17 @@ public InetAddress readInetAddress() { @Override public Bytes readBytes() { - LOG.trace("Reading arbitrary bytes, currentItem = {}", currentItem); checkElt("arbitrary bytes value"); final Bytes res = payloadSlice(); setTo(nextItem()); - LOG.trace("Read arbitrary bytes {}, currentItem = {}", res, currentItem); return res; } @Override public Bytes32 readBytes32() { - LOG.trace("Reading Bytes32, currentItem = {}", currentItem); checkElt("32 bytes value", 32); final Bytes32 res = inputSlice32(currentPayloadOffset); setTo(nextItem()); - LOG.trace("Read Bytes32 {}, currentItem = {}", res, currentItem); return res; } @@ -494,11 +478,6 @@ public int enterList() { * @return -1 if skipCount==true, otherwise, the number of item of the entered list. */ public int enterList(final boolean skipCount) { - LOG.trace( - "Entering list (depth = {}, endOfListOffset = {}, currentItem = {})", - depth, - endOfListOffset, - currentItem); if (currentItem >= size) { throw error("Cannot enter a lists, input is fully consumed"); } @@ -541,13 +520,6 @@ public int enterList(final boolean skipCount) { // And lastly reset on the list first element before returning setTo(listStart); - LOG.trace( - "Entered list (depth = {}, endOfListOffset = {}, currentItem = {}, listEnd = {}, elements = {})", - depth, - endOfListOffset, - currentItem, - listEnd, - count); return count; } @@ -562,12 +534,6 @@ public void leaveListLenient() { } private void leaveList(final boolean ignoreRest) { - LOG.trace( - "Leaving list (depth = {}, endOfListOffset = {}, ignoreRest = {}, currentItem = {}", - depth, - endOfListOffset, - ignoreRest, - currentItem); checkState(depth > 0, "Not within an RLP list"); if (!ignoreRest) { @@ -576,12 +542,6 @@ private void leaveList(final boolean ignoreRest) { } --depth; - LOG.trace( - "Left list (depth = {}, endOfListOffset = {}, ignoreRes = {}, currentItem = {}", - depth, - endOfListOffset, - ignoreRest, - currentItem); } @Override diff --git a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java index 0f711dc3d69..73eebbb212e 100644 --- a/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java +++ b/ethereum/rlp/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java @@ -23,11 +23,8 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.MutableBytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; abstract class AbstractRLPOutput implements RLPOutput { - private static final Logger LOG = LoggerFactory.getLogger(AbstractRLPOutput.class); /* * The algorithm implemented works as follows: * @@ -82,12 +79,10 @@ private int currentList() { @Override public void writeBytes(final Bytes v) { - LOG.trace("Writing bytes {}", v); checkState( stackSize > 1 || values.isEmpty(), "Terminated RLP output, cannot add more elements"); values.add(v); payloadSizes[currentList()] += RLPEncodingHelpers.elementSize(v); - LOG.trace("Wrote bytes {}", v); } @Override @@ -102,12 +97,6 @@ public void writeRaw(final Bytes v) { @Override public void startList() { - LOG.trace( - "Starting list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", - stackSize, - listsCount, - payloadSizes, - parentListStack); values.add(LIST_MARKER); ++listsCount; // we'll add a new element to payloadSizes ++stackSize; // and to the list stack. @@ -123,22 +112,10 @@ public void startList() { // The new current list size is store in the slot we just made room for by incrementing // listsCount parentListStack[stackSize - 1] = listsCount - 1; - LOG.trace( - "Started list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", - stackSize, - listsCount, - payloadSizes, - parentListStack); } @Override public void endList() { - LOG.trace( - "Ending list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", - stackSize, - listsCount, - payloadSizes, - parentListStack); checkState(stackSize > 1, "LeaveList() called with no prior matching startList()"); final int current = currentList(); @@ -148,12 +125,6 @@ public void endList() { // We just finished an item of our parent list, add it to that parent list size now. final int newCurrent = currentList(); payloadSizes[newCurrent] += finishedListSize; - LOG.trace( - "Ended list (stackSize = {}, listsCount = {}, payloadSizes = {}, parentListStack = {})", - stackSize, - listsCount, - payloadSizes, - parentListStack); } /** From 03ee34ac38763e60baee274207e56fc170d34cb2 Mon Sep 17 00:00:00 2001 From: Matilda Clerke Date: Wed, 29 Jan 2025 09:45:35 +1100 Subject: [PATCH 20/20] spotless Signed-off-by: Matilda Clerke --- .../AccessListTransactionEncoder.java | 38 +++++++++--------- .../CodeDelegationTransactionEncoder.java | 40 +++++++++---------- .../encoding/EIP1559TransactionEncoder.java | 24 +++++------ .../encoding/FrontierTransactionEncoder.java | 18 ++++----- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java index 4ed9566197e..54bf8cc41ec 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/AccessListTransactionEncoder.java @@ -31,25 +31,25 @@ public class AccessListTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput rlpOutput) { - rlpOutput.startList(); - encodeAccessListInner( - transaction.getChainId(), - transaction.getNonce(), - transaction.getGasPrice().orElseThrow(), - transaction.getGasLimit(), - transaction.getTo(), - transaction.getValue(), - transaction.getPayload(), - transaction - .getAccessList() - .orElseThrow( - () -> - new IllegalStateException( - "Developer error: access list should be guaranteed to be present")), - rlpOutput); - rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); - writeSignature(transaction, rlpOutput); - rlpOutput.endList(); + rlpOutput.startList(); + encodeAccessListInner( + transaction.getChainId(), + transaction.getNonce(), + transaction.getGasPrice().orElseThrow(), + transaction.getGasLimit(), + transaction.getTo(), + transaction.getValue(), + transaction.getPayload(), + transaction + .getAccessList() + .orElseThrow( + () -> + new IllegalStateException( + "Developer error: access list should be guaranteed to be present")), + rlpOutput); + rlpOutput.writeIntScalar(transaction.getSignature().getRecId()); + writeSignature(transaction, rlpOutput); + rlpOutput.endList(); } public static void encodeAccessListInner( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java index 1ca23eaa2c9..c34de129251 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/CodeDelegationTransactionEncoder.java @@ -63,25 +63,25 @@ private static void encodeAuthorizationDetails( } public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); - out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeAccessList(out, transaction.getAccessList()); - encodeCodeDelegationInner( - transaction - .getCodeDelegationList() - .orElseThrow( - () -> - new IllegalStateException( - "Developer error: the transaction should be guaranteed to have a code delegation authorizations here")), - out); - writeSignatureAndRecoveryId(transaction, out); - out.endList(); + out.startList(); + out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); + out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeAccessList(out, transaction.getAccessList()); + encodeCodeDelegationInner( + transaction + .getCodeDelegationList() + .orElseThrow( + () -> + new IllegalStateException( + "Developer error: the transaction should be guaranteed to have a code delegation authorizations here")), + out); + writeSignatureAndRecoveryId(transaction, out); + out.endList(); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java index d4438e0ede9..bc8e41da820 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/EIP1559TransactionEncoder.java @@ -25,17 +25,17 @@ public class EIP1559TransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); - out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeAccessList(out, transaction.getAccessList()); - writeSignatureAndRecoveryId(transaction, out); - out.endList(); + out.startList(); + out.writeBigIntegerScalar(transaction.getChainId().orElseThrow()); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getMaxPriorityFeePerGas().orElseThrow()); + out.writeUInt256Scalar(transaction.getMaxFeePerGas().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeAccessList(out, transaction.getAccessList()); + writeSignatureAndRecoveryId(transaction, out); + out.endList(); } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java index 1703a1c61c0..039c3871040 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/FrontierTransactionEncoder.java @@ -23,14 +23,14 @@ public class FrontierTransactionEncoder { public static void encode(final Transaction transaction, final RLPOutput out) { - out.startList(); - out.writeLongScalar(transaction.getNonce()); - out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); - out.writeLongScalar(transaction.getGasLimit()); - out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); - out.writeUInt256Scalar(transaction.getValue()); - out.writeBytes(transaction.getPayload()); - writeSignatureAndV(transaction, out); - out.endList(); + out.startList(); + out.writeLongScalar(transaction.getNonce()); + out.writeUInt256Scalar(transaction.getGasPrice().orElseThrow()); + out.writeLongScalar(transaction.getGasLimit()); + out.writeBytes(transaction.getTo().map(Bytes::copy).orElse(Bytes.EMPTY)); + out.writeUInt256Scalar(transaction.getValue()); + out.writeBytes(transaction.getPayload()); + writeSignatureAndV(transaction, out); + out.endList(); } }