Fix log index in transaction receipt (#6206)

* [#6204] Fix log index in transaction receipt

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Update CHANGELOG.md

Add to bug fixes.

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Update tests

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Directly sum log size with known index

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Minor change to gasUsed

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Place hash and index first

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Test without parallel()

Signed-off-by: Wetitpig <winsto003@hotmail.com>

* Rewrite header hash as map chain

Signed-off-by: Wetitpig <winsto003@hotmail.com>

---------

Signed-off-by: Wetitpig <winsto003@hotmail.com>
pull/6222/head
Wetitpig 12 months ago committed by GitHub
parent 8f5a4443cc
commit 65d7033cd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 8
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionReceiptResult.java
  3. 47
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
  4. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/TransactionReceiptWithMetadata.java
  5. 9
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/graphql/TransactionDataFetcherTest.java
  6. 9
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthGetTransactionReceiptTest.java

@ -17,6 +17,7 @@
### Bug fixes
- Fix Docker image name clash between Besu and evmtool [#6194](https://github.com/hyperledger/besu/pull/6194)
- Fix `logIndex` in `eth_getTransactionReceipt` JSON RPC method [#6206](https://github.com/hyperledger/besu/pull/6206)
## 23.10.2

@ -92,7 +92,8 @@ public abstract class TransactionReceiptResult {
receiptWithMetadata.getBlockNumber(),
txn.getHash(),
receiptWithMetadata.getBlockHash(),
receiptWithMetadata.getTransactionIndex());
receiptWithMetadata.getTransactionIndex(),
receiptWithMetadata.getLogIndexOffset());
this.logsBloom = receipt.getBloomFilter().toString();
this.to = txn.getTo().map(Bytes::toHexString).orElse(null);
this.transactionHash = txn.getHash().toString();
@ -192,14 +193,15 @@ public abstract class TransactionReceiptResult {
final long blockNumber,
final Hash transactionHash,
final Hash blockHash,
final int transactionIndex) {
final int transactionIndex,
final int logIndexOffset) {
final List<TransactionReceiptLogResult> logResults = new ArrayList<>(logs.size());
for (int i = 0; i < logs.size(); i++) {
final Log log = logs.get(i);
logResults.add(
new TransactionReceiptLogResult(
log, blockNumber, transactionHash, blockHash, transactionIndex, i));
log, blockNumber, transactionHash, blockHash, transactionIndex, i + logIndexOffset));
}
return logResults;

@ -183,8 +183,7 @@ public class BlockchainQueries {
*/
public Optional<UInt256> storageAt(
final Address address, final UInt256 storageIndex, final long blockNumber) {
final Hash blockHash =
getBlockHeaderByNumber(blockNumber).map(BlockHeader::getHash).orElse(Hash.EMPTY);
final Hash blockHash = getBlockHashByNumber(blockNumber).orElse(Hash.EMPTY);
return storageAt(address, storageIndex, blockHash);
}
@ -211,8 +210,7 @@ public class BlockchainQueries {
* @return The balance of the account in Wei.
*/
public Optional<Wei> accountBalance(final Address address, final long blockNumber) {
final Hash blockHash =
getBlockHeaderByNumber(blockNumber).map(BlockHeader::getHash).orElse(Hash.EMPTY);
final Hash blockHash = getBlockHashByNumber(blockNumber).orElse(Hash.EMPTY);
return accountBalance(address, blockHash);
}
@ -236,8 +234,7 @@ public class BlockchainQueries {
* @return The code associated with this address.
*/
public Optional<Bytes> getCode(final Address address, final long blockNumber) {
final Hash blockHash =
getBlockHeaderByNumber(blockNumber).map(BlockHeader::getHash).orElse(Hash.EMPTY);
final Hash blockHash = getBlockHashByNumber(blockNumber).orElse(Hash.EMPTY);
return getCode(address, blockHash);
}
@ -263,13 +260,7 @@ public class BlockchainQueries {
if (outsideBlockchainRange(blockNumber)) {
return Optional.empty();
}
return Optional.of(
blockchain
.getBlockHashByNumber(blockNumber)
.flatMap(this::blockByHashWithTxHashes)
.map(BlockWithMetadata::getTransactions)
.map(List::size)
.orElse(-1));
return blockchain.getBlockHashByNumber(blockNumber).map(this::getTransactionCount);
}
/**
@ -624,22 +615,25 @@ public class BlockchainQueries {
// getTransactionLocation should not return if the TX or block doesn't exist, so throwing
// on a missing optional is appropriate.
final TransactionLocation location = maybeLocation.get();
final Block block = blockchain.getBlockByHash(location.getBlockHash()).orElseThrow();
final Transaction transaction =
block.getBody().getTransactions().get(location.getTransactionIndex());
final Hash blockhash = location.getBlockHash();
final int transactionIndex = location.getTransactionIndex();
final Block block = blockchain.getBlockByHash(blockhash).orElseThrow();
final Transaction transaction = block.getBody().getTransactions().get(transactionIndex);
final BlockHeader header = block.getHeader();
final List<TransactionReceipt> transactionReceipts =
blockchain.getTxReceipts(blockhash).orElseThrow();
final TransactionReceipt transactionReceipt =
transactionReceipts.get(location.getTransactionIndex());
final TransactionReceipt transactionReceipt = transactionReceipts.get(transactionIndex);
long gasUsed = transactionReceipt.getCumulativeGasUsed();
if (location.getTransactionIndex() > 0) {
gasUsed =
gasUsed
- transactionReceipts.get(location.getTransactionIndex() - 1).getCumulativeGasUsed();
int logIndexOffset = 0;
if (transactionIndex > 0) {
gasUsed -= transactionReceipts.get(transactionIndex - 1).getCumulativeGasUsed();
logIndexOffset =
IntStream.range(0, transactionIndex)
.map(i -> transactionReceipts.get(i).getLogsList().size())
.sum();
}
Optional<Long> maybeBlobGasUsed =
@ -653,13 +647,14 @@ public class BlockchainQueries {
transactionReceipt,
transaction,
transactionHash,
location.getTransactionIndex(),
transactionIndex,
gasUsed,
header.getBaseFee(),
blockhash,
header.getNumber(),
maybeBlobGasUsed,
maybeBlobGasPrice));
maybeBlobGasPrice,
logIndexOffset));
}
/**
@ -1075,7 +1070,7 @@ public class BlockchainQueries {
break;
}
logIndexOffset += receipts.get(i).getLogs().size();
logIndexOffset += receipts.get(i).getLogsList().size();
}
return logIndexOffset;

@ -32,6 +32,7 @@ public class TransactionReceiptWithMetadata {
private final Transaction transaction;
private final Optional<Long> blobGasUsed;
private final Optional<Wei> blobGasPrice;
private final int logIndexOffset;
private TransactionReceiptWithMetadata(
final TransactionReceipt receipt,
@ -43,7 +44,8 @@ public class TransactionReceiptWithMetadata {
final Hash blockHash,
final long blockNumber,
final Optional<Long> blobGasUsed,
final Optional<Wei> blobGasPrice) {
final Optional<Wei> blobGasPrice,
final int logIndexOffset) {
this.receipt = receipt;
this.transactionHash = transactionHash;
this.transactionIndex = transactionIndex;
@ -54,6 +56,7 @@ public class TransactionReceiptWithMetadata {
this.transaction = transaction;
this.blobGasUsed = blobGasUsed;
this.blobGasPrice = blobGasPrice;
this.logIndexOffset = logIndexOffset;
}
public static TransactionReceiptWithMetadata create(
@ -66,7 +69,8 @@ public class TransactionReceiptWithMetadata {
final Hash blockHash,
final long blockNumber,
final Optional<Long> blobGasUsed,
final Optional<Wei> blobGasPrice) {
final Optional<Wei> blobGasPrice,
final int logIndexOffset) {
return new TransactionReceiptWithMetadata(
receipt,
transaction,
@ -77,7 +81,8 @@ public class TransactionReceiptWithMetadata {
blockHash,
blockNumber,
blobGasUsed,
blobGasPrice);
blobGasPrice,
logIndexOffset);
}
public TransactionReceipt getReceipt() {
@ -121,4 +126,8 @@ public class TransactionReceiptWithMetadata {
public Optional<Wei> getBlobGasPrice() {
return blobGasPrice;
}
public int getLogIndexOffset() {
return logIndexOffset;
}
}

@ -75,7 +75,8 @@ class TransactionDataFetcherTest extends AbstractDataFetcherTest {
fakedHash,
1,
Optional.empty(),
Optional.empty());
Optional.empty(),
0);
when(query.transactionReceiptByTransactionHash(any(), any()))
.thenReturn(Optional.of(transactionReceiptWithMetadata));
@ -109,7 +110,8 @@ class TransactionDataFetcherTest extends AbstractDataFetcherTest {
fakedHash,
1,
Optional.of(0L),
Optional.of(Wei.ZERO));
Optional.of(Wei.ZERO),
0);
when(query.transactionReceiptByTransactionHash(any(), any()))
.thenReturn(Optional.of(transactionReceiptWithMetadata));
@ -143,7 +145,8 @@ class TransactionDataFetcherTest extends AbstractDataFetcherTest {
fakedHash,
1,
Optional.of(blobGasUsed),
Optional.of(blobGasPrice));
Optional.of(blobGasPrice),
0);
when(query.transactionReceiptByTransactionHash(any(), any()))
.thenReturn(Optional.of(transactionReceiptWithMetadata));

@ -103,7 +103,8 @@ public class EthGetTransactionReceiptTest {
blockHash,
4,
Optional.empty(),
Optional.empty());
Optional.empty(),
0);
private final TransactionReceiptWithMetadata rootReceiptWithMetaData =
TransactionReceiptWithMetadata.create(
rootReceipt,
@ -115,7 +116,8 @@ public class EthGetTransactionReceiptTest {
blockHash,
4,
Optional.empty(),
Optional.empty());
Optional.empty(),
0);
private final ProtocolSpec rootTransactionTypeSpec =
new ProtocolSpec(
@ -243,7 +245,8 @@ public class EthGetTransactionReceiptTest {
blockHash,
4,
Optional.empty(),
Optional.empty());
Optional.empty(),
0);
when(blockchainQueries.transactionReceiptByTransactionHash(receiptHash, protocolSchedule))
.thenReturn(Optional.of(transactionReceiptWithMetadata));
when(protocolSchedule.getByBlockHeader(blockHeader(1))).thenReturn(rootTransactionTypeSpec);

Loading…
Cancel
Save