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_TOO_LARGE (-30) - Event size exceeds maximum allowed
  • TN_VM_ERR_SYSCALL_INVALID_ADDRESS (-21) - Invalid virtual address for event data
  • TN_VM_ERR_SYSCALL_INSUFFICIENT_PAGES (-25) - 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 Structure

Each event is stored with metadata:
struct event_record {
    tn_txn_event_metadata_t metadata;  // Event metadata
    uchar data[];                      // Event data payload
};

Event Metadata

The system automatically adds metadata to each event:
  • 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 "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;
}