|
3 | 3 | import static org.junit.Assert.assertThrows; |
4 | 4 | import static org.mockito.ArgumentMatchers.any; |
5 | 5 | import static org.mockito.Mockito.doThrow; |
| 6 | +import static org.mockito.Mockito.mock; |
6 | 7 | import static org.mockito.Mockito.spy; |
| 8 | +import static org.mockito.Mockito.when; |
7 | 9 | import static org.tron.common.utils.Commons.adjustAssetBalanceV2; |
8 | 10 | import static org.tron.common.utils.Commons.adjustTotalShieldedPoolValue; |
9 | 11 | import static org.tron.common.utils.Commons.getExchangeStoreFinal; |
|
16 | 18 | import com.google.common.collect.Sets; |
17 | 19 | import com.google.protobuf.Any; |
18 | 20 | import com.google.protobuf.ByteString; |
| 21 | +import java.lang.reflect.Field; |
| 22 | +import java.lang.reflect.Method; |
19 | 23 | import java.nio.charset.StandardCharsets; |
20 | 24 | import java.util.ArrayList; |
21 | 25 | import java.util.Arrays; |
22 | 26 | import java.util.List; |
23 | 27 | import java.util.Map; |
24 | 28 | import java.util.Set; |
| 29 | +import java.util.concurrent.LinkedBlockingQueue; |
25 | 30 | import java.util.concurrent.atomic.AtomicInteger; |
26 | 31 | import java.util.stream.Collectors; |
27 | 32 | import java.util.stream.IntStream; |
|
32 | 37 | import org.tron.common.BaseMethodTest; |
33 | 38 | import org.tron.common.TestConstants; |
34 | 39 | import org.tron.common.crypto.ECKey; |
| 40 | +import org.tron.common.logsfilter.EventPluginLoader; |
| 41 | +import org.tron.common.logsfilter.trigger.ContractLogTrigger; |
35 | 42 | import org.tron.common.runtime.RuntimeImpl; |
36 | 43 | import org.tron.common.utils.ByteArray; |
37 | 44 | import org.tron.common.utils.Commons; |
@@ -1292,6 +1299,79 @@ public void blockTrigger() { |
1292 | 1299 | Assert.assertEquals(TronError.ErrCode.EVENT_SUBSCRIBE_ERROR, thrown.getErrCode()); |
1293 | 1300 | } |
1294 | 1301 |
|
| 1302 | + @Test |
| 1303 | + public void testReOrgContractTriggerClearsMap() throws Exception { |
| 1304 | + long forkBlockNum = 1L; |
| 1305 | + // set up eventPluginLoaded and mock EventPluginLoader so the guard inside |
| 1306 | + // clearSolidityContractTriggerCache actually executes |
| 1307 | + ReflectUtils.setFieldValue(dbManager, "eventPluginLoaded", true); |
| 1308 | + EventPluginLoader mockLoader = mock(EventPluginLoader.class); |
| 1309 | + when(mockLoader.isSolidityLogTriggerEnable()).thenReturn(true); |
| 1310 | + when(mockLoader.isSolidityEventTriggerEnable()).thenReturn(false); |
| 1311 | + Field instanceField = EventPluginLoader.class.getDeclaredField("instance"); |
| 1312 | + instanceField.setAccessible(true); |
| 1313 | + EventPluginLoader originalLoader = (EventPluginLoader) instanceField.get(null); |
| 1314 | + instanceField.set(null, mockLoader); |
| 1315 | + |
| 1316 | + Args.getSolidityContractLogTriggerMap() |
| 1317 | + .computeIfAbsent(forkBlockNum, k -> new LinkedBlockingQueue<>()) |
| 1318 | + .offer(new ContractLogTrigger()); |
| 1319 | + Args.getSolidityContractEventTriggerMap() |
| 1320 | + .computeIfAbsent(forkBlockNum, k -> new LinkedBlockingQueue<>()) |
| 1321 | + .offer(new org.tron.common.logsfilter.trigger.ContractEventTrigger()); |
| 1322 | + |
| 1323 | + try { |
| 1324 | + Method method = dbManager.getClass() |
| 1325 | + .getDeclaredMethod("clearSolidityContractTriggerCache", long.class); |
| 1326 | + method.setAccessible(true); |
| 1327 | + method.invoke(dbManager, forkBlockNum); |
| 1328 | + |
| 1329 | + // assert inside try — before finally cleans up — to verify actual cache clear |
| 1330 | + Assert.assertNull(Args.getSolidityContractLogTriggerMap().get(forkBlockNum)); |
| 1331 | + Assert.assertNull(Args.getSolidityContractEventTriggerMap().get(forkBlockNum)); |
| 1332 | + } finally { |
| 1333 | + instanceField.set(null, originalLoader); |
| 1334 | + ReflectUtils.setFieldValue(dbManager, "eventPluginLoaded", false); |
| 1335 | + Args.getSolidityContractLogTriggerMap().clear(); |
| 1336 | + Args.getSolidityContractEventTriggerMap().clear(); |
| 1337 | + } |
| 1338 | + } |
| 1339 | + |
| 1340 | + @Test |
| 1341 | + public void testClearSolidityContractTriggerCache() throws Exception { |
| 1342 | + long blockNum = 999L; |
| 1343 | + ReflectUtils.setFieldValue(dbManager, "eventPluginLoaded", true); |
| 1344 | + EventPluginLoader mockLoader = mock(EventPluginLoader.class); |
| 1345 | + when(mockLoader.isSolidityLogTriggerEnable()).thenReturn(true); |
| 1346 | + when(mockLoader.isSolidityEventTriggerEnable()).thenReturn(true); |
| 1347 | + Field instanceField = EventPluginLoader.class.getDeclaredField("instance"); |
| 1348 | + instanceField.setAccessible(true); |
| 1349 | + EventPluginLoader originalLoader = (EventPluginLoader) instanceField.get(null); |
| 1350 | + instanceField.set(null, mockLoader); |
| 1351 | + |
| 1352 | + Args.getSolidityContractLogTriggerMap() |
| 1353 | + .computeIfAbsent(blockNum, k -> new LinkedBlockingQueue<>()) |
| 1354 | + .offer(new ContractLogTrigger()); |
| 1355 | + Args.getSolidityContractEventTriggerMap() |
| 1356 | + .computeIfAbsent(blockNum, k -> new LinkedBlockingQueue<>()); |
| 1357 | + Assert.assertFalse(Args.getSolidityContractLogTriggerMap().isEmpty()); |
| 1358 | + |
| 1359 | + try { |
| 1360 | + Method method = Manager.class.getDeclaredMethod("clearSolidityContractTriggerCache", |
| 1361 | + long.class); |
| 1362 | + method.setAccessible(true); |
| 1363 | + method.invoke(dbManager, blockNum); |
| 1364 | + |
| 1365 | + Assert.assertNull(Args.getSolidityContractLogTriggerMap().get(blockNum)); |
| 1366 | + Assert.assertNull(Args.getSolidityContractEventTriggerMap().get(blockNum)); |
| 1367 | + } finally { |
| 1368 | + instanceField.set(null, originalLoader); |
| 1369 | + ReflectUtils.setFieldValue(dbManager, "eventPluginLoaded", false); |
| 1370 | + Args.getSolidityContractLogTriggerMap().clear(); |
| 1371 | + Args.getSolidityContractEventTriggerMap().clear(); |
| 1372 | + } |
| 1373 | + } |
| 1374 | + |
1295 | 1375 | public void adjustBalance(AccountStore accountStore, byte[] accountAddress, long amount) |
1296 | 1376 | throws BalanceInsufficientException { |
1297 | 1377 | Commons.adjustBalance(accountStore, accountAddress, amount, |
|
0 commit comments