Skip to content

Conversation

@Matilda-Clerke
Copy link
Contributor

PR description

This PR adds SyncTransactionReceipt (similar to SyncBlockBody) to allow us to perform sync operations without fully parsing and duplicating the backing data. (PoC branch at #9416)

…ilise raw Bytes

Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>
Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>
Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>
Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>
Signed-off-by: Matilda Clerke <matilda.clerke@consensys.net>
@Matilda-Clerke Matilda-Clerke enabled auto-merge (squash) January 7, 2026 03:14
transactionTypeCode,
statusOrStateRoot,
cumulativeGas,
bloomFilter == null ? LogsBloomFilter.builder().insertRawLogs(logs).build() : bloomFilter,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when we are syncing we should not have to deal with the case that we have a legacy receipt without bloom filter. I think that it only us removing the bloom filter when we are storing receipts in a compacted form in the db.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'll have to double check the PoC branch, but removing the bloom filter stuff should simplify this a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we do need the bloom filters to calculate the receipts root


@Test
public void testDecodeLegacyReceipt() {
final Hash stateRoot = Hash.fromHexStringLenient("01");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

01 should be the status then, not the state root.
A legacy receipt can contain the state root, so maybe we should add a test with a state root as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case it's just using 01 as some test data. As it's used in the Hash class, it's always going to be 32 bytes long and the content doesn't actually matter, as long as it remains the same in the result

Copy link
Contributor Author

@Matilda-Clerke Matilda-Clerke Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed these to a random 32 byte value instead, to make it clearer that this isn't a status

There's also no reason to write a separate test for receipt with a status instead of stateRoot as the code doesn't do anything different either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, state root should only be possible in legacy receipts. I will have another look at the code :-)

: transactionByteRlp;
Bytes cumulativeGasUsed = input.readBytes();
List<List<Bytes>> logs = parseLogs(input);
Bytes bloomFilter = LogsBloomFilter.builder().insertRawLogs(logs).build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we actually need the bloomFilter later when we received an eth69 receipt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I wrote this class to mirror the functionality of the TransactionReceiptDecoder, which does give eth69 receipts a bloom filter in the same manner. This may be removed if we don't need bloom filters for syncing.

public Builder insertRawLogs(final Collection<List<Bytes>> logs) {
logs.forEach(
(bytesList) ->
insertRawLog(bytesList.getFirst(), bytesList.subList(1, bytesList.size() - 1)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could just call insertBytes for each log

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so too initially, but it seems the data portion of the log is actually not included in the bloom filter. This is why you can see I'm using a subList on the second parameter.

The insertRawLog method also makes it clear and explicit exactly which Bytes is the address and which Bytes are log topics, which imo is preferable to just inserting them into the filter.

@Matilda-Clerke Matilda-Clerke requested a review from pinges January 8, 2026 05:04
@macfarla
Copy link
Contributor

macfarla commented Jan 8, 2026

My comments have been addressed. Will leave to sync experts to approve

@bretk1989
Copy link

bretk1989 commented Jan 8, 2026 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants