events.go
Overview
The `events.go` file is part of the Thorchain-specific functionality within a Cosmos SDK-based blockchain data processing system. Its primary purpose is to define Thorchain-specific blockchain event types and provide mechanisms to parse raw block events into strongly typed event structures. It also converts these typed events into generalized message formats used elsewhere in the system.
Specifically, this file:
Defines concrete Go structs representing Thorchain blockchain event types such as fees and outbound transfers.
Implements
ParseBlockEvents, which converts raw ABCI (Application Blockchain Interface) events into typed events and organizes them by message index.Provides
typedEventsToMessagesto transform typed events into generic message representations consumable by the broader Cosmos SDK-based transaction processing framework.
This file acts as a domain-specific event parsing layer that abstracts raw blockchain event data into structured, typed objects, enabling downstream components like transaction parsers and API handlers to work with clear and consistent event data.
Detailed Explanation
Types
TypedEvent (interface)
type TypedEvent interface{}
A marker interface representing any typed event parsed from raw blockchain events.
Implemented by concrete event structs such as
EventFeeandEventOutbound.
EventFee
type EventFee struct {
TxID string `json:"tx_id"`
Coins string `json:"coins"`
PoolDeduct string `json:"pool_deduct"`
SynthUnits string `json:"synth_units"`
}
Represents a fee-related blockchain event in Thorchain.
Fields:
TxID: Transaction ID associated with the fee.Coins: Amount and denomination of coins paid as a fee.PoolDeduct: Amount deducted from liquidity pools.SynthUnits: Synthetic units involved (Thorchain-specific concept).
**Usage example:**
When parsing a block event with type `"fee"`, an `EventFee` instance is created and populated with attribute data extracted from the event.
EventOutbound
type EventOutbound struct {
InTxID string `json:"in_tx_id"`
ID string `json:"id"`
Chain string `json:"chain"`
From string `json:"from"`
To string `json:"to"`
Coin string `json:"coin"`
Memo string `json:"memo"`
}
Represents an outbound transfer event from Thorchain.
Fields:
InTxID: ID of the inbound transaction triggering this outbound event.ID: Unique event identifier.Chain: Blockchain chain name (e.g., BTC, ETH).From: Sending address.To: Receiving address.Coin: Coin amount and denomination string.Memo: Memo or note attached to the transaction.
**Usage example:**
When parsing a block event with type `"outbound"`, an `EventOutbound` instance is created and populated accordingly.
Functions
ParseBlockEvents
func ParseBlockEvents(blockEvents []cosmos.ABCIEvent) (cosmos.EventsByMsgIndex, []TypedEvent, error)
Purpose: Parses a slice of raw ABCI events from a block and returns two key data structures:
EventsByMsgIndex: A map organizing event attributes by message index and event type.A slice of typed events (
TypedEvent), each representing a parsed event of a known type.
Parameters:
blockEvents []cosmos.ABCIEvent: Raw events from the blockchain block.
Returns:
cosmos.EventsByMsgIndex: Map with keys as message indices (string) mapping to event types and their attributes.[]TypedEvent: Slice of parsed event structs typed asTypedEvent.error: Non-nil if parsing fails.
Implementation Details:
Iterates over each event.
For recognized event types (
"fee","outbound"), creates an instance of the corresponding struct.Converts event attributes (key-value pairs) into a JSON object by quoting attribute values.
Unmarshals this JSON into the typed event struct.
Builds maps of attributes by event type and message index.
Skips unknown event types.
Returns an error if JSON marshaling or unmarshaling fails.
Usage example:
blockEvents := []cosmos.ABCIEvent{...} // obtained from block results
eventsByMsgIndex, typedEvents, err := ParseBlockEvents(blockEvents)
if err != nil {
// handle error
}
// typedEvents now contains parsed EventFee and EventOutbound structs
// eventsByMsgIndex organizes attributes by message index and event type
typedEventsToMessages
func typedEventsToMessages(events []TypedEvent) []cosmos.Message
Purpose: Converts a slice of typed Thorchain events into a slice of generic Cosmos SDK
Messagestructs for further processing.Parameters:
events []TypedEvent: Slice of typed events, typically output fromParseBlockEvents.
Returns:
[]cosmos.Message: Slice ofcosmos.Messageinstances representing parsed events as messages.
Implementation Details:
Iterates over each event.
For
EventOutboundevents:Attempts to parse the coin string into a structured coin.
Logs error if parsing fails but continues processing.
Constructs a
cosmos.Messagewith:Addresses involved (
FromandTo).Index (string representation of event index).
Origin, From, and To addresses.
Type
"outbound".Value converted using helper
cosmos.CoinToValue, which creates acosmos.Valuefrom ansdk.Coin.
Ignores other event types.
Usage example:
typedEvents := []TypedEvent{...} // parsed events
messages := typedEventsToMessages(typedEvents)
// messages now contains Cosmos SDK compatible messages derived from outbound events
Important Implementation Details and Algorithms
Event Attribute Parsing and JSON Conversion:
To convert raw event attributes (which are key-value string pairs) into typed Go structs, the code builds a JSON object with quoted string values. This approach ensures correct unmarshaling of string fields, avoiding issues with raw attribute values that may contain special characters.Message Indexing:
Events are indexed by their position in the block event slice (i), converted to string keys. This allows correlating multiple events belonging to the same message within a block.Selective Event Typing:
Currently, only"fee"and"outbound"event types are parsed into specific structs. Unknown event types are ignored, which keeps parsing focused and efficient.Error Handling:
JSON marshaling and unmarshaling errors are propagated immediately, preventing silent failures.Typed Event to Message Conversion:
Converts domain-specific events into a more generic format, enabling interoperability with other Cosmos SDK-based components.
Interaction with Other Parts of the System
Thorchain Transaction Parsing (
tx.go):
The typed events produced byParseBlockEventsare inputs to transaction parsers that synthesize full transactions from block events.Cosmos SDK Integration:
The genericcosmos.Messagestructs output bytypedEventsToMessagesintegrate with broader Cosmos transaction processing logic.Affiliate Fee Indexing:
TheEventFeestructures feed into modules tracking affiliate fees.API Server and Handlers:
The parsed event data supports REST and WebSocket APIs by providing structured event information for clients.Logging:
Uses package-level logger to report coin parsing errors during typed event to message conversion.
Usage Example
import (
"github.com/shapeshift/unchained/pkg/cosmos"
"gitlab.com/thorchain/thornode/v3/common"
"github.com/thorchain/thornode/v3/pkg/thorchain"
)
// Assume blockEvents is obtained from block results
blockEvents := []cosmos.ABCIEvent{...}
eventsByMsgIndex, typedEvents, err := thorchain.ParseBlockEvents(blockEvents)
if err != nil {
// handle error
}
// Convert typed events to generic messages
messages := thorchain.typedEventsToMessages(typedEvents)
for _, msg := range messages {
fmt.Printf("Message Type: %s, From: %s, To: %s, Value: %+v\n",
msg.Type, msg.From, msg.To, msg.Value)
}
Diagram: Structure and Workflow of events.go
flowchart TD
subgraph Input
A[Raw ABCI Events (blockEvents)]
end
subgraph ParseBlockEvents
B[Identify Event Type]
C[Create Typed Event Struct]
D[Build JSON from Attributes]
E[Unmarshal JSON into Typed Struct]
F[Map Attributes by MsgIndex & EventType]
end
subgraph Output
G[EventsByMsgIndex (map[string]map[string]Attributes)]
H[TypedEvents ([]TypedEvent)]
end
subgraph typedEventsToMessages
I[Iterate TypedEvents]
J[Handle EventOutbound]
K[Parse Coin]
L[Construct cosmos.Message]
M[Return []cosmos.Message]
end
A --> B --> C --> D --> E --> F --> G
F --> H
H --> I --> J --> K --> L --> M
Summary
The `events.go` file is a critical utility component in the Thorchain coinstack, responsible for:
Defining Thorchain-specific blockchain event types.
Parsing raw block-level ABCI events into strongly typed Go structs.
Organizing event attributes by message index and event type.
Converting typed events into generic Cosmos SDK messages for downstream processing.
By encapsulating the complexity of raw blockchain event parsing and providing a structured event representation, this file enables accurate and efficient transaction synthesis, fee indexing, and API serving tailored to Thorchain's unique blockchain event semantics.