tx.go
Overview
The `tx.go` file within the Thorchain coinstack is responsible for **parsing, synthesizing, and formatting Thorchain-specific transactions** from raw blockchain data. It bridges the gap between low-level blockchain events and high-level transaction representations consumable by the API layer and clients.
Thorchain's blockchain emits unique event types and message structures that require custom decoding beyond generic Cosmos SDK processing. This file implements functions to:
Query transaction history related to a public key using block and event data.
Parse Thorchain and Cosmos SDK messages into enriched, structured message objects.
Construct synthetic transactions from block-end events unique to Thorchain (especially outbound transfers).
Format these synthetic transactions into standard
cosmos.Txstructures for API consumption.
This file interacts closely with:
The Cosmos SDK HTTP client and block services for querying blockchain data.
Thorchain-specific event types and parsing utilities.
The API server and handler which expose parsed transaction data via REST/WebSocket.
Detailed Explanation of Functions
1. GetTxHistory
func GetTxHistory(handler *cosmos.Handler, pubkey string, cursor string, pageSize int) (api.TxHistory, error)
Purpose
Retrieves a paginated list of transactions involving a specific public key (`pubkey`). It searches blocks for events associated with the pubkey, parses those events into transactions, and returns a structured transaction history.
Parameters
handler *cosmos.Handler: The Cosmos SDK blockchain handler, providing HTTP client and block services.pubkey string: The public key or address for which to fetch transaction history.cursor string: Pagination cursor to continue from a previous query.pageSize int: Number of transactions to return per page.
Returns
api.TxHistory: A structured transaction history object containing transactions and pagination info.error: Any error encountered during querying or parsing.
Implementation Details
Defines an internal
requestfunction that:Searches blocks with events matching the pubkey.
For each block found, fetches block results (events).
Iterates block events, calling
GetTxFromBlockEventsto synthesize transactions.Filters transactions only involving the target pubkey.
Combines standard Cosmos transaction sources with a custom "swap" source filtering outbound events to the pubkey.
Calls
handler.HTTPClient.GetTxHistorywith these sources.Wraps the result into a
cosmos.TxHistorystructure.
Usage Example
txHistory, err := GetTxHistory(handler, "thor1xyz...", "", 25)
if err != nil {
log.Fatal(err)
}
for _, tx := range txHistory.Txs {
fmt.Println(tx.TxID, tx.BlockHeight)
}
2. ParseMessages
func ParseMessages(msgs []sdk.Msg, events cosmos.EventsByMsgIndex) []cosmos.Message
Purpose
Parses arrays of Cosmos SDK and Thorchain-specific messages, combining them with associated blockchain events to produce a list of enriched, structured messages. Handles special Thorchain message types and synthesizes additional messages based on event data.
Parameters
msgs []sdk.Msg: List of Cosmos SDK messages from a transaction.events cosmos.EventsByMsgIndex: Map of events keyed by message index, containing event attributes.
Returns
[]cosmos.Message: List of parsed and enriched message objects with fields likeFrom,To,Value, andType.
Implementation Details
Skips parsing if the first message group contains an error event.
Iterates over each message:
For
MsgSend: extracts sender, recipient, and amount.For
MsgDeposit: parses deposit info, detects relatedwithdraw,refund,outbound,tcy_unstake, andrune_pool_withdrawevents to generate synthetic messages.For
MsgObservedTxQuorum: parsestcy_claimtransfers.Unhandled messages are recursively parsed by the generic Cosmos parser.
Uses
cosmos.CoinToValueto convert coin amounts to a uniform value structure.
Usage Example
messages := ParseMessages(txMsgs, txEvents)
for _, msg := range messages {
fmt.Printf("Type: %s, From: %s, To: %s, Value: %s\n", msg.Type, msg.From, msg.To, msg.Value.Amount)
}
3. GetTxFromBlockEvents
func GetTxFromBlockEvents(eventCache map[string]interface{}, blockHeader types.Header, blockEvents []cosmos.ABCIEvent, eventIndex int, latestHeight int, denom string, nativeFee int) (*ResultTx, error)
Purpose
Creates a **synthetic transaction** from Thorchain block-end events, especially handling outbound transfers that do not correspond to explicit on-chain transactions.
Parameters
eventCache map[string]interface{}: Cache to store parsed block events and typed events for reuse.blockHeader types.Header: Block header containing height, hash, and timestamp.blockEvents []cosmos.ABCIEvent: Raw ABCI events from the block.eventIndex int: Index of the event within the block to process.latestHeight int: Latest block height known to compute confirmations.denom string: The native denomination (e.g., "rune").nativeFee int: The native fee amount to apply if no explicit fee event.
Returns
*ResultTx: Pointer to a synthetic transaction structure, or nil if no synthetic transaction is created.error: Any error encountered during processing.
Implementation Details
Defines an internal
matchFeefunction that tries to find a matching fee event for the transaction ID among typed events; falls back to native fee if none found.Parses block events only once, caching parsed events and typed events.
Extracts the typed event at the specified index.
Creates a new
ResultTxwith block metadata, events, and messages.If the typed event is an
EventOutbound, it:Sets the TxID to the inbound TxID referenced in the outbound event.
Applies associated memos and fees.
Returns the constructed synthetic transaction.
For other event types, returns nil indicating no synthetic transaction.
Usage Example
tx, err := GetTxFromBlockEvents(eventCache, header, events, 0, latestHeight, "rune", 37500)
if err != nil {
log.Fatal(err)
}
if tx != nil {
// process synthetic tx
}
4. formatTx
func formatTx(tx *ResultTx) (*cosmos.Tx, error)
Purpose
Formats a `ResultTx` synthetic transaction into a standard `cosmos.Tx` structure compatible with the Cosmos SDK API framework.
Parameters
tx *ResultTx: The synthetic transaction to format.
Returns
*cosmos.Tx: A Cosmos SDK compatible transaction object.error: Any error during formatting (rare).
Implementation Details
Maps fields from
ResultTxsuch as TxID, block hash, height, timestamp, confirmations, events, messages, and fee.Sets
GasWantedandGasUsedto"0"since synthetic transactions do not have gas info.Computes confirmations as
latestHeight - BlockHeight + 1.
Usage Example
cosmosTx, err := formatTx(resultTx)
if err != nil {
log.Fatal(err)
}
fmt.Println(cosmosTx.TxID)
Important Implementation Details and Algorithms
Event Caching:
To optimize performance when parsing multiple events in the same block,GetTxFromBlockEventscaches parsed block events (events) and typed events (typedEvents) in a map keyed by"events"and"typedEvents". This avoids redundant parsing.Synthetic Transaction Creation:
Thorchain emits block-end events (likeEventOutbound) that represent important transactions not explicitly included as on-chain messages. The code detects these and synthesizesResultTxobjects to capture them.Fee Matching:
The native fee is not always explicitly represented in events. ThematchFeefunction attempts to find a fee event matching the transaction ID; if none is found, it falls back to a default native fee amount.Message Parsing with Event Augmentation:
When parsingMsgDeposit, the code enriches the event data with memo values and creates synthetic messages to represent related outbound transfers, refunds, or withdrawals derived from separate events attached to the deposit message index.Filtering Transactions by Address:
During transaction history retrieval, transactions are filtered to include only those where the target pubkey is involved in any address extracted from the transaction's events or messages.
Interaction with Other System Components
Cosmos Handler and HTTP Client:
GetTxHistoryrelies on the Cosmos SDK HTTP client to search blocks and fetch block results, enabling event-driven transaction reconstruction.Thorchain Event Types & Parsing Utilities:
Uses Thorchain-specific event types (EventOutbound,EventFee, etc.) and parsing functions likeParseBlockEventsandtypedEventsToMessagesto decode raw blockchain events.API Layer:
The API server invokesGetTxHistoryandParseMessagesto serve transaction data to clients through REST and WebSocket endpoints.Affiliate Fee Indexer (Indirect):
Parsed transactions and messages feed into the affiliate fee indexer to track revenue generated from affiliate fees.
Visual Diagram: Function Interaction Flowchart
flowchart TD
A[GetTxHistory] --> B[Search Blocks for Pubkey Events]
B --> C[Fetch Block Results per Block]
C --> D[For Each Block Event Index]
D --> E[GetTxFromBlockEvents]
E --> F[ParseBlockEvents (cache)]
E --> G[Match Fee Event or Use Native Fee]
E --> H[Create ResultTx (Synthetic Tx)]
D --> I[Filter Tx by Pubkey]
I --> J[Collect Transactions]
J --> K[Return TxHistory]
subgraph ParseMessages Flow
L[ParseMessages]
L --> M[Handle MsgSend]
L --> N[Handle MsgDeposit]
N --> O[Detect Withdraw/Refund/Outbound Events]
N --> P[Create Synthetic Messages]
L --> Q[Handle MsgObservedTxQuorum]
L --> R[Handle Unhandled Messages (Cosmos Parser)]
end
Summary
The `tx.go` file provides critical Thorchain-specific transaction parsing capabilities:
It retrieves transaction history by searching and interpreting Thorchain block events tied to a public key.
It parses Thorchain-native messages and synthesizes additional message objects based on event metadata.
It creates synthetic transactions from block-end outbound events to capture Thorchain-specific blockchain semantics.
It formats transactions into Cosmos SDK compatible structures for API exposure.
This file embodies the core logic that transforms raw Thorchain blockchain data into rich, structured transaction data, enabling client applications to present accurate and comprehensive transaction histories and details.
Appendix: Example Usage Scenario
// Initialize handler and required parameters
handler := cosmos.NewHandler(...)
pubkey := "thor1xyz..."
pageSize := 50
// Fetch transaction history for pubkey
txHistory, err := GetTxHistory(handler, pubkey, "", pageSize)
if err != nil {
log.Fatalf("failed to get tx history: %v", err)
}
// Iterate and print transaction IDs
for _, tx := range txHistory.Txs {
fmt.Printf("TxID: %s, Height: %d\n", tx.TxID, tx.BlockHeight)
}
// Parse messages from a transaction
for _, tx := range txHistory.Txs {
messages := ParseMessages(tx.Messages, tx.Events)
for _, msg := range messages {
fmt.Printf("Message Type: %s, From: %s, To: %s, Value: %s\n",
msg.Type, msg.From, msg.To, msg.Value.Amount)
}
}
This example demonstrates retrieving and parsing transaction history for a given Thorchain address.
*End of documentation for `tx.go`.*