Skip to main content

Overview

The emit_event syscall records an event in the transaction’s event log. Events are stored in anonymous memory and become part of the transaction’s output for external consumption.

Syscall Code

Code: 0x0D (TN_SYSCALL_CODE_EMIT_EVENT)

C SDK Function

ulong tsys_emit_event(void const* data, ulong data_sz);

Arguments

data
void const*
required
Pointer to the event data to be recorded.
data_sz
ulong
required
Size of the event data in bytes. Must not exceed the maximum event size.

Return Value

Returns a syscall result code:
Success
ulong
  • TN_VM_SYSCALL_SUCCESS (0) - Event recorded successfully
Error Codes
ulong
  • TN_VM_ERR_SYSCALL_EVENT_IS_ZERO_SIZE (-46) - Event size must be greater than zero
  • TN_VM_ERR_SYSCALL_EVENT_TOO_LARGE (-31) - Event size exceeds maximum allowed
  • TN_VM_ERR_SYSCALL_INVALID_ADDRESS (-22) - Invalid virtual address for event data
  • TN_VM_ERR_SYSCALL_INSUFFICIENT_PAGES (-26) - Not enough pages to expand event storage

Resource Consumption

Compute Units

  • Base cost: TN_VM_SYSCALL_BASE_COST (512 units)
  • Event cost: Additional units equal to event data size in bytes
  • Total formula: base_cost + data_sz

Memory Pages

  • Event storage: Pages allocated for event storage in anonymous memory segment
  • Automatic expansion: Event storage segment grows as needed (page-aligned)
  • Metadata overhead: Additional space for event metadata per event

Side Effects

  • Event storage: Copies event data to transaction’s event log
  • Memory allocation: May expand event storage segment if needed
  • Event counter: Increments the transaction’s event count

Event Metadata

The runtime automatically adds internal metadata to each emitted event before exposing it in transaction output. That metadata is not part of the public C SDK surface, so programs should treat the event payload they pass to tsys_emit_event() as the only SDK-facing input. The metadata attached by the runtime includes:
  • Event size: Size of the event data
  • Call index: Unique identifier for the program invocation
  • Program account index: Index of the program that emitted the event

Storage Management

  • Events are stored in a grow-up anonymous memory segment
  • Storage automatically expands as needed (page-aligned)
  • Events are stored sequentially in the order emitted
  • Multiple events can be emitted by the same program

Size Limitations

  • Maximum event size: UINT_MAX bytes (4GB)
  • Practical limits imposed by available memory pages
  • Event storage competes with other memory allocations

Usage Notes

  • Events are included in transaction output for external consumption
  • Event order is preserved within the transaction
  • Events from different programs are distinguished by metadata
  • Event data format is application-defined

Example

#include <thru-sdk/c/tn_sdk_syscall.h>
#include <string.h>
#include <stdint.h>

// Emit a simple text event
char event_msg[] = "Account created successfully";
ulong result = tsys_emit_event(event_msg, strlen(event_msg));

// Emit structured event data
struct account_created_event {
    uint64_t account_id;
    uint64_t initial_balance;
    char account_type[16];
} event = {
    .account_id = 12345,
    .initial_balance = 1000000,
    .account_type = "savings"
};

result = tsys_emit_event(&event, sizeof(event));

// Emit multiple related events
for (int i = 0; i < transfer_count; i++) {
    struct transfer_event {
        uint64_t from_account;
        uint64_t to_account;
        uint64_t amount;
    } transfer = {
        .from_account = transfers[i].from,
        .to_account = transfers[i].to,
        .amount = transfers[i].amount
    };
    
    result = tsys_emit_event(&transfer, sizeof(transfer));
    if (result != TN_VM_SYSCALL_SUCCESS) break;
}