Skip to content

Commit 956d98f

Browse files
refactor: reduced complexity of buildReceiptRootHashes; fixed potential bug with type=0 handling (#4921)
Signed-off-by: Bartosz Solka <bartosz.solka@blockydevs.com>
1 parent 1e221d3 commit 956d98f

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

packages/relay/src/lib/services/ethService/blockService/blockWorker.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,43 @@ function populateSyntheticTransactions(
131131
return [...deduplicatedInput, ...syntheticTransactions.values()] as Transaction[] | string[];
132132
}
133133

134+
/**
135+
* Builds Ethereum-style receipt objects.
136+
*
137+
* Groups mirror node logs and contract results by transaction hash, derives a numeric
138+
* transaction index for each transaction, orders them by that index, and then produces
139+
* `IReceiptRootHash` entries with cumulative gas, status, bloom, and logs.
140+
*
141+
* @param txHashes - Transaction hashes for the block.
142+
* @param contractResults - Contract results returned by the mirror node for the block.
143+
* @param logs - Log entries returned by the mirror node for the block.
144+
* @returns An array of receipt objects, sorted by transaction index.
145+
*/
134146
function buildReceiptRootHashes(txHashes: string[], contractResults: any[], logs: Log[]): IReceiptRootHash[] {
135147
const items: {
136148
transactionIndex: number;
137149
logsPerTx: Log[];
138150
crPerTx: any[];
139151
}[] = [];
140152

153+
//build lookup maps for logs and contract results by transaction hash to avoid O(n^2) complexity
154+
const logsByTxHash = new Map<string, Log[]>();
155+
for (const log of logs) {
156+
const list = logsByTxHash.get(log.transactionHash) ?? [];
157+
list.push(log);
158+
logsByTxHash.set(log.transactionHash, list);
159+
}
160+
161+
const contractResultsByHash = new Map<string, any[]>();
162+
for (const cr of contractResults) {
163+
const list = contractResultsByHash.get(cr.hash) ?? [];
164+
list.push(cr);
165+
contractResultsByHash.set(cr.hash, list);
166+
}
167+
141168
for (const txHash of txHashes) {
142-
const logsPerTx: Log[] = logs.filter((log) => log.transactionHash === txHash);
143-
const crPerTx: any[] = contractResults.filter((cr) => cr.hash === txHash);
169+
const logsPerTx: Log[] = logsByTxHash.get(txHash) ?? [];
170+
const crPerTx: any[] = contractResultsByHash.get(txHash) ?? [];
144171

145172
// Derive numeric transaction index (for ordering)
146173
let txIndexNum: number = 0;
@@ -172,7 +199,10 @@ function buildReceiptRootHashes(txHashes: string[], contractResults: any[], logs
172199

173200
receipts.push({
174201
transactionIndex: transactionIndexHex,
175-
type: crPerTx.length && crPerTx[0].type ? intToHex(crPerTx[0].type) : null,
202+
type:
203+
crPerTx.length > 0 && crPerTx[0].type !== undefined && crPerTx[0].type !== null
204+
? intToHex(crPerTx[0].type)
205+
: null,
176206
root: crPerTx.length ? crPerTx[0].root : constants.ZERO_HEX_32_BYTE,
177207
status: crPerTx.length ? crPerTx[0].status : constants.ONE_HEX,
178208
cumulativeGasUsed: intToHex(cumulativeGas),

0 commit comments

Comments
 (0)