Skip to content

Commit 2660165

Browse files
pdrobnjakclaude
andcommitted
perf: add GIGA_SUPPRESS_COSMOS_EVENTS flag to skip dead event emission
Cosmos-level events (coin_spent, coin_received, transfer, etc.) emitted during giga executor tx execution are never consumed: the ExecTxResult is built without populating the Events field, and events are not consensus-critical (stripped from deterministicExecTxResult). EVM logs (Solidity events) flow through a completely separate path (tempState.logs -> receipts + MsgEVMTransactionResponse) and are unaffected. When GIGA_SUPPRESS_COSMOS_EVENTS=true: - EventManager.EmitEvent/EmitEvents return immediately (no mutex, no append, no bech32 encoding in event attributes) - Snapshot() creates suppressed EventManagers - Finalize() skips the flushEvents() consolidation loop This eliminates ~55s of mutex contention per 30s profile window: - AccAddress.String() bech32 cache mutex: ~27s - EventManager.EmitEvents RWMutex: ~28s Also updates benchmark/analysis/ with findings from the AccAddress.String sync.Map optimization (PR #2902) and this event suppression discovery. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent fce7d6a commit 2660165

4 files changed

Lines changed: 49 additions & 10 deletions

File tree

app/app.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ type gigaBlockCache struct {
327327
blockCtx vm.BlockContext
328328
chainConfig *ethparams.ChainConfig
329329
baseFee *big.Int
330+
331+
// when true, Cosmos-level events (coin_spent, coin_received, etc.) are
332+
// discarded during giga executor tx execution. EVM logs are unaffected.
333+
suppressCosmosEvents bool
330334
}
331335

332336
func newGigaBlockCache(ctx sdk.Context, keeper *gigaevmkeeper.Keeper) (*gigaBlockCache, error) {
@@ -340,10 +344,11 @@ func newGigaBlockCache(ctx sdk.Context, keeper *gigaevmkeeper.Keeper) (*gigaBloc
340344
chainConfig := evmtypes.DefaultChainConfig().EthereumConfigWithSstore(chainID, &sstore)
341345
baseFee := keeper.GetBaseFee(ctx)
342346
return &gigaBlockCache{
343-
chainID: chainID,
344-
blockCtx: *blockCtx,
345-
chainConfig: chainConfig,
346-
baseFee: baseFee,
347+
chainID: chainID,
348+
blockCtx: *blockCtx,
349+
chainConfig: chainConfig,
350+
baseFee: baseFee,
351+
suppressCosmosEvents: os.Getenv("GIGA_SUPPRESS_COSMOS_EVENTS") == "true",
347352
}, nil
348353
}
349354

@@ -1793,6 +1798,9 @@ func (app *App) executeEVMTxWithGigaExecutor(ctx sdk.Context, msg *evmtypes.MsgE
17931798

17941799
// Create state DB for this transaction
17951800
stateDB := gigaevmstate.NewDBImpl(ctx, &app.GigaEvmKeeper, false)
1801+
if cache.suppressCosmosEvents {
1802+
stateDB.SuppressCosmosEvents()
1803+
}
17961804
defer stateDB.Cleanup()
17971805

17981806
// Get gas pool (mutated per tx, cannot be cached)

giga/deps/xevm/state/state.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ func (s *DBImpl) HasSelfDestructed(acc common.Address) bool {
102102
}
103103

104104
func (s *DBImpl) Snapshot() int {
105-
newCtx := s.ctx.WithMultiStore(s.ctx.MultiStore().CacheMultiStore()).WithEventManager(sdk.NewEventManager())
105+
em := sdk.NewEventManager()
106+
if s.cosmosEventsSuppressed {
107+
em = sdk.NewSuppressedEventManager()
108+
}
109+
newCtx := s.ctx.WithMultiStore(s.ctx.MultiStore().CacheMultiStore()).WithEventManager(em)
106110
s.snapshottedCtxs = append(s.snapshottedCtxs, s.ctx)
107111
s.ctx = newCtx
108112
version := len(s.snapshottedCtxs) - 1

giga/deps/xevm/state/statedb.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ type DBImpl struct {
3939
// for cases like bank.send_native, we want to suppress transfer events
4040
eventsSuppressed bool
4141

42+
// when true, all Cosmos-level events (coin_spent, coin_received, etc.)
43+
// are discarded. EVM logs are unaffected. Use this on the giga executor
44+
// path where Cosmos events are constructed but never consumed.
45+
cosmosEventsSuppressed bool
46+
4247
logger *tracing.Hooks
4348
}
4449

@@ -66,6 +71,10 @@ func (s *DBImpl) EnableEvents() {
6671
s.eventsSuppressed = false
6772
}
6873

74+
func (s *DBImpl) SuppressCosmosEvents() {
75+
s.cosmosEventsSuppressed = true
76+
}
77+
6978
func (s *DBImpl) SetLogger(logger *tracing.Hooks) {
7079
s.logger = logger
7180
}
@@ -112,11 +121,14 @@ func (s *DBImpl) Finalize() (surplus sdk.Int, err error) {
112121
s.clearAccountStateIfDestructed(s.tempState)
113122

114123
s.flushCtxs()
115-
// write all events in order
116-
for i := 1; i < len(s.snapshottedCtxs); i++ {
117-
s.flushEvents(s.snapshottedCtxs[i])
124+
// write all events in order (skip when cosmos events are suppressed —
125+
// the EventManagers are no-ops so there is nothing to consolidate)
126+
if !s.cosmosEventsSuppressed {
127+
for i := 1; i < len(s.snapshottedCtxs); i++ {
128+
s.flushEvents(s.snapshottedCtxs[i])
129+
}
130+
s.flushEvents(s.ctx)
118131
}
119-
s.flushEvents(s.ctx)
120132

121133
surplus = s.tempState.surplus
122134
return

sei-cosmos/types/events.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import (
2828
type EventManager struct {
2929
events Events
3030

31-
mtx sync.RWMutex
31+
mtx sync.RWMutex
32+
suppressed bool
3233
}
3334

3435
// Common Event Types and Attributes
@@ -55,11 +56,22 @@ func NewEventManager() *EventManager {
5556
return &em
5657
}
5758

59+
// NewSuppressedEventManager returns an EventManager that silently discards all
60+
// emitted events. Use this on hot paths where events are constructed but never
61+
// consumed (e.g. the giga executor) to avoid mutex contention, bech32 encoding
62+
// in event attributes, and allocation overhead.
63+
func NewSuppressedEventManager() *EventManager {
64+
return &EventManager{suppressed: true}
65+
}
66+
5867
func (em *EventManager) Events() Events { return em.events }
5968

6069
// EmitEvent stores a single Event object.
6170
// Deprecated: Use EmitTypedEvent
6271
func (em *EventManager) EmitEvent(event Event) {
72+
if em.suppressed {
73+
return
74+
}
6375
em.mtx.Lock()
6476
defer em.mtx.Unlock()
6577
em.events = em.events.AppendEvent(event)
@@ -68,6 +80,9 @@ func (em *EventManager) EmitEvent(event Event) {
6880
// EmitEvents stores a series of Event objects.
6981
// Deprecated: Use EmitTypedEvents
7082
func (em *EventManager) EmitEvents(events Events) {
83+
if em.suppressed {
84+
return
85+
}
7186
em.mtx.Lock()
7287
defer em.mtx.Unlock()
7388
em.events = em.events.AppendEvents(events)

0 commit comments

Comments
 (0)