Skip to content

Commit 4026637

Browse files
fab-10jflo
authored andcommitted
Fix and test that the BlockAwareOperationTracer methods are invoked the correct number of times (besu-eth#6259)
* Test that the BlockAwareOperationTracer are invoked the correct number of times * Remove redundant calls to traceEndBlock Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net> Signed-off-by: jflo <justin+github@florentine.us>
1 parent 9fa6dbe commit 4026637

File tree

2 files changed

+94
-11
lines changed

2 files changed

+94
-11
lines changed

besu/src/main/java/org/hyperledger/besu/services/TraceServiceImpl.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ public void trace(
162162
blocks.forEach(
163163
block -> {
164164
results.addAll(trace(blockchain, block, chainUpdater, tracer));
165-
tracer.traceEndBlock(block.getHeader(), block.getBody());
166165
});
167166
afterTracing.accept(chainUpdater.getNextUpdater());
168167
return Optional.of(results);
@@ -180,7 +179,6 @@ private Optional<List<TransactionProcessingResult>> trace(
180179
block.getHash(),
181180
traceableState ->
182181
Optional.of(trace(blockchain, block, new ChainUpdater(traceableState), tracer)));
183-
tracer.traceEndBlock(block.getHeader(), block.getBody());
184182

185183
return results;
186184
}

besu/src/test/java/org/hyperledger/besu/services/TraceServiceImplTest.java

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,46 @@
1515
package org.hyperledger.besu.services;
1616

1717
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.fail;
19+
import static org.mockito.ArgumentMatchers.any;
20+
import static org.mockito.ArgumentMatchers.anyBoolean;
21+
import static org.mockito.ArgumentMatchers.anyLong;
22+
import static org.mockito.ArgumentMatchers.eq;
23+
import static org.mockito.Mockito.mock;
24+
import static org.mockito.Mockito.verify;
1825

1926
import org.hyperledger.besu.datatypes.Address;
27+
import org.hyperledger.besu.datatypes.Hash;
2028
import org.hyperledger.besu.datatypes.Transaction;
2129
import org.hyperledger.besu.datatypes.Wei;
2230
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
2331
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
32+
import org.hyperledger.besu.ethereum.core.Block;
2433
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
2534
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
2635
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
2736
import org.hyperledger.besu.evm.log.Log;
2837
import org.hyperledger.besu.evm.worldstate.WorldView;
38+
import org.hyperledger.besu.plugin.data.BlockBody;
39+
import org.hyperledger.besu.plugin.data.BlockHeader;
2940
import org.hyperledger.besu.plugin.data.BlockTraceResult;
3041
import org.hyperledger.besu.plugin.data.TransactionTraceResult;
3142
import org.hyperledger.besu.plugin.services.TraceService;
3243
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
3344

45+
import java.util.HashSet;
3446
import java.util.List;
47+
import java.util.Optional;
48+
import java.util.Set;
49+
import java.util.stream.LongStream;
3550

3651
import org.apache.tuweni.bytes.Bytes;
3752
import org.junit.jupiter.api.BeforeEach;
3853
import org.junit.jupiter.api.Test;
39-
import org.junit.runner.RunWith;
40-
import org.mockito.junit.MockitoJUnitRunner;
54+
import org.junit.jupiter.api.extension.ExtendWith;
55+
import org.mockito.junit.jupiter.MockitoExtension;
4156

42-
@RunWith(MockitoJUnitRunner.class)
57+
@ExtendWith(MockitoExtension.class)
4358
class TraceServiceImplTest {
4459

4560
TraceService traceService;
@@ -73,19 +88,40 @@ void shouldRetrieveStateUpdatePostTracingForOneBlock() {
7388
final long persistedNonceForAccount =
7489
worldStateArchive.getMutable().get(addressToVerify).getNonce();
7590

91+
final long blockNumber = 2;
92+
93+
final BlockAwareOperationTracer opTracer = mock(BlockAwareOperationTracer.class);
94+
7695
traceService.trace(
77-
2,
78-
2,
96+
blockNumber,
97+
blockNumber,
7998
worldState -> {
8099
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(1);
81100
},
82101
worldState -> {
83102
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(2);
84103
},
85-
BlockAwareOperationTracer.NO_TRACING);
104+
opTracer);
86105

87106
assertThat(worldStateArchive.getMutable().get(addressToVerify).getNonce())
88107
.isEqualTo(persistedNonceForAccount);
108+
109+
final Block tracedBlock = blockchain.getBlockByNumber(blockNumber).get();
110+
111+
verify(opTracer).traceStartBlock(tracedBlock.getHeader(), tracedBlock.getBody());
112+
113+
tracedBlock
114+
.getBody()
115+
.getTransactions()
116+
.forEach(
117+
tx -> {
118+
verify(opTracer).traceStartTransaction(any(), eq(tx));
119+
verify(opTracer)
120+
.traceEndTransaction(
121+
any(), eq(tx), anyBoolean(), any(), any(), anyLong(), anyLong());
122+
});
123+
124+
verify(opTracer).traceEndBlock(tracedBlock.getHeader(), tracedBlock.getBody());
89125
}
90126

91127
@Test
@@ -96,20 +132,44 @@ void shouldRetrieveStateUpdatePostTracingForAllBlocks() {
96132
final long persistedNonceForAccount =
97133
worldStateArchive.getMutable().get(addressToVerify).getNonce();
98134

135+
final long startBlock = 1;
136+
final long endBlock = 32;
137+
final BlockAwareOperationTracer opTracer = mock(BlockAwareOperationTracer.class);
138+
99139
traceService.trace(
100-
0,
101-
32,
140+
startBlock,
141+
endBlock,
102142
worldState -> {
103143
assertThat(worldState.get(addressToVerify).getNonce()).isEqualTo(0);
104144
},
105145
worldState -> {
106146
assertThat(worldState.get(addressToVerify).getNonce())
107147
.isEqualTo(persistedNonceForAccount);
108148
},
109-
BlockAwareOperationTracer.NO_TRACING);
149+
opTracer);
110150

111151
assertThat(worldStateArchive.getMutable().get(addressToVerify).getNonce())
112152
.isEqualTo(persistedNonceForAccount);
153+
154+
LongStream.rangeClosed(startBlock, endBlock)
155+
.mapToObj(blockchain::getBlockByNumber)
156+
.map(Optional::get)
157+
.forEach(
158+
tracedBlock -> {
159+
verify(opTracer).traceStartBlock(tracedBlock.getHeader(), tracedBlock.getBody());
160+
tracedBlock
161+
.getBody()
162+
.getTransactions()
163+
.forEach(
164+
tx -> {
165+
verify(opTracer).traceStartTransaction(any(), eq(tx));
166+
verify(opTracer)
167+
.traceEndTransaction(
168+
any(), eq(tx), anyBoolean(), any(), any(), anyLong(), anyLong());
169+
});
170+
171+
verify(opTracer).traceEndBlock(tracedBlock.getHeader(), tracedBlock.getBody());
172+
});
113173
}
114174

115175
@Test
@@ -197,8 +257,16 @@ private static class TxStartEndTracer implements BlockAwareOperationTracer {
197257
public long txEndGasUsed;
198258
public Long txEndTimeNs;
199259

260+
private final Set<Transaction> traceStartTxCalled = new HashSet<>();
261+
private final Set<Transaction> traceEndTxCalled = new HashSet<>();
262+
private final Set<Hash> traceStartBlockCalled = new HashSet<>();
263+
private final Set<Hash> traceEndBlockCalled = new HashSet<>();
264+
200265
@Override
201266
public void traceStartTransaction(final WorldView worldView, final Transaction transaction) {
267+
if (!traceStartTxCalled.add(transaction)) {
268+
fail("traceStartTransaction already called for tx " + transaction);
269+
}
202270
txStartWorldView = worldView;
203271
txStartTransaction = transaction;
204272
}
@@ -212,6 +280,9 @@ public void traceEndTransaction(
212280
final List<Log> logs,
213281
final long gasUsed,
214282
final long timeNs) {
283+
if (!traceEndTxCalled.add(transaction)) {
284+
fail("traceEndTransaction already called for tx " + transaction);
285+
}
215286
txEndWorldView = worldView;
216287
txEndTransaction = transaction;
217288
txEndStatus = status;
@@ -220,5 +291,19 @@ public void traceEndTransaction(
220291
txEndGasUsed = gasUsed;
221292
txEndTimeNs = timeNs;
222293
}
294+
295+
@Override
296+
public void traceStartBlock(final BlockHeader blockHeader, final BlockBody blockBody) {
297+
if (!traceStartBlockCalled.add(blockHeader.getBlockHash())) {
298+
fail("traceStartBlock already called for block " + blockHeader);
299+
}
300+
}
301+
302+
@Override
303+
public void traceEndBlock(final BlockHeader blockHeader, final BlockBody blockBody) {
304+
if (!traceEndBlockCalled.add(blockHeader.getBlockHash())) {
305+
fail("traceEndBlock already called for block " + blockHeader);
306+
}
307+
}
223308
}
224309
}

0 commit comments

Comments
 (0)