From 3f53a78dcf55bf2fec64593e4f1e787d5a036f16 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Mon, 26 Jan 2026 11:10:05 +0800 Subject: [PATCH 1/2] feat(evnet): optimize concurrent write issues for contract events --- .../services/event/RealtimeEventService.java | 29 +++++++++++++------ .../services/event/SolidEventService.java | 21 ++++++++++---- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java b/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java index 093594f1c95..e362f7220ac 100644 --- a/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java +++ b/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java @@ -4,6 +4,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; + +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -20,6 +22,9 @@ public class RealtimeEventService { private EventPluginLoader instance = EventPluginLoader.getInstance(); + @Getter + private static Object contractLock = new Object(); + @Autowired private Manager manager; @@ -99,24 +104,30 @@ public void flush(BlockEvent blockEvent, boolean isRemove) { logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId().getString()); } else { blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { - v.setTriggerName(Trigger.CONTRACTEVENT_TRIGGER_NAME); - v.setRemoved(isRemove); - EventPluginLoader.getInstance().postContractEventTrigger(v); + synchronized (contractLock) { + v.setTriggerName(Trigger.CONTRACTEVENT_TRIGGER_NAME); + v.setRemoved(isRemove); + EventPluginLoader.getInstance().postContractEventTrigger(v); + } }); } } if (instance.isContractLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { - v.setTriggerName(Trigger.CONTRACTLOG_TRIGGER_NAME); - v.setRemoved(isRemove); - EventPluginLoader.getInstance().postContractLogTrigger(v); - }); - if (instance.isContractLogTriggerRedundancy()) { - blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { + synchronized (contractLock) { v.setTriggerName(Trigger.CONTRACTLOG_TRIGGER_NAME); v.setRemoved(isRemove); EventPluginLoader.getInstance().postContractLogTrigger(v); + } + }); + if (instance.isContractLogTriggerRedundancy()) { + blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { + synchronized (contractLock) { + v.setTriggerName(Trigger.CONTRACTLOG_TRIGGER_NAME); + v.setRemoved(isRemove); + EventPluginLoader.getInstance().postContractLogTrigger(v); + } }); } } diff --git a/framework/src/main/java/org/tron/core/services/event/SolidEventService.java b/framework/src/main/java/org/tron/core/services/event/SolidEventService.java index 6102a87f892..cba77dbf04a 100644 --- a/framework/src/main/java/org/tron/core/services/event/SolidEventService.java +++ b/framework/src/main/java/org/tron/core/services/event/SolidEventService.java @@ -91,21 +91,30 @@ public void flush(BlockEvent blockEvent) { logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId()); } else { blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { - v.setTriggerName(Trigger.SOLIDITYEVENT_TRIGGER_NAME); - EventPluginLoader.getInstance().postSolidityEventTrigger(v); + synchronized (RealtimeEventService.getContractLock()) { + v.setTriggerName(Trigger.SOLIDITYEVENT_TRIGGER_NAME); + v.setRemoved(false); + EventPluginLoader.getInstance().postSolidityEventTrigger(v); + } }); } } if (instance.isSolidityLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { - v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); - EventPluginLoader.getInstance().postSolidityLogTrigger(v); + synchronized (RealtimeEventService.getContractLock()) { + v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); + v.setRemoved(false); + EventPluginLoader.getInstance().postSolidityLogTrigger(v); + } }); if (instance.isSolidityLogTriggerRedundancy()) { blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { - v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); - EventPluginLoader.getInstance().postSolidityLogTrigger(v); + synchronized (RealtimeEventService.getContractLock()) { + v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); + v.setRemoved(false); + EventPluginLoader.getInstance().postSolidityLogTrigger(v); + } }); } } From a491083052a9bb936798434487a6b014d769fd42 Mon Sep 17 00:00:00 2001 From: zeusoo001 Date: Tue, 27 Jan 2026 11:16:18 +0800 Subject: [PATCH 2/2] optimize lock granularity --- .../services/event/RealtimeEventService.java | 34 ++++++++----------- .../services/event/SolidEventService.java | 34 ++++++++----------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java b/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java index e362f7220ac..5aee55b1c13 100644 --- a/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java +++ b/framework/src/main/java/org/tron/core/services/event/RealtimeEventService.java @@ -99,36 +99,32 @@ public void flush(BlockEvent blockEvent, boolean isRemove) { } } - if (instance.isContractEventTriggerEnable()) { - if (blockEvent.getSmartContractTrigger() == null) { - logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId().getString()); - } else { - blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { - synchronized (contractLock) { + synchronized (contractLock) { + if (instance.isContractEventTriggerEnable()) { + if (blockEvent.getSmartContractTrigger() == null) { + logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId().getString()); + } else { + blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { v.setTriggerName(Trigger.CONTRACTEVENT_TRIGGER_NAME); v.setRemoved(isRemove); EventPluginLoader.getInstance().postContractEventTrigger(v); - } - }); + }); + } } - } - if (instance.isContractLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { - blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { - synchronized (contractLock) { + if (instance.isContractLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { + blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { v.setTriggerName(Trigger.CONTRACTLOG_TRIGGER_NAME); v.setRemoved(isRemove); EventPluginLoader.getInstance().postContractLogTrigger(v); - } - }); - if (instance.isContractLogTriggerRedundancy()) { - blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { - synchronized (contractLock) { + }); + if (instance.isContractLogTriggerRedundancy()) { + blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { v.setTriggerName(Trigger.CONTRACTLOG_TRIGGER_NAME); v.setRemoved(isRemove); EventPluginLoader.getInstance().postContractLogTrigger(v); - } - }); + }); + } } } } diff --git a/framework/src/main/java/org/tron/core/services/event/SolidEventService.java b/framework/src/main/java/org/tron/core/services/event/SolidEventService.java index cba77dbf04a..0614541f16f 100644 --- a/framework/src/main/java/org/tron/core/services/event/SolidEventService.java +++ b/framework/src/main/java/org/tron/core/services/event/SolidEventService.java @@ -86,36 +86,32 @@ public void flush(BlockEvent blockEvent) { } } - if (instance.isSolidityEventTriggerEnable()) { - if (blockEvent.getSmartContractTrigger() == null) { - logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId()); - } else { - blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { - synchronized (RealtimeEventService.getContractLock()) { + synchronized (RealtimeEventService.getContractLock()) { + if (instance.isSolidityEventTriggerEnable()) { + if (blockEvent.getSmartContractTrigger() == null) { + logger.warn("SmartContractTrigger is null. {}", blockEvent.getBlockId()); + } else { + blockEvent.getSmartContractTrigger().getContractEventTriggers().forEach(v -> { v.setTriggerName(Trigger.SOLIDITYEVENT_TRIGGER_NAME); v.setRemoved(false); EventPluginLoader.getInstance().postSolidityEventTrigger(v); - } - }); + }); + } } - } - if (instance.isSolidityLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { - blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { - synchronized (RealtimeEventService.getContractLock()) { + if (instance.isSolidityLogTriggerEnable() && blockEvent.getSmartContractTrigger() != null) { + blockEvent.getSmartContractTrigger().getContractLogTriggers().forEach(v -> { v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); v.setRemoved(false); EventPluginLoader.getInstance().postSolidityLogTrigger(v); - } - }); - if (instance.isSolidityLogTriggerRedundancy()) { - blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { - synchronized (RealtimeEventService.getContractLock()) { + }); + if (instance.isSolidityLogTriggerRedundancy()) { + blockEvent.getSmartContractTrigger().getRedundancies().forEach(v -> { v.setTriggerName(Trigger.SOLIDITYLOG_TRIGGER_NAME); v.setRemoved(false); EventPluginLoader.getInstance().postSolidityLogTrigger(v); - } - }); + }); + } } }