Skip to content

account_compress

View as Markdown

The account_compress syscall compresses an account by setting the COMPRESSED flag. It accepts a state proof as input so the runtime can validate and commit the state-tree transition.

The syscall does not generate or return a proof for the newly compressed state. It returns only a result code. After the compression transaction is committed and indexed, request a separate EXISTING proof from GenerateStateProof when preparing to decompress the account.

Code: 0x08 (TN_SYSCALL_CODE_ACCOUNT_COMPRESS)

ulong tsys_account_compress(ulong account_idx, void const* proof, ulong proof_sz);

account_idx · ulong · required

Index of the account to compress. Must be writable in the transaction.

proof · void const · required*

Pointer to the state proof data.

proof_sz · ulong · required

Size of the state proof data in bytes.

Returns a syscall result code:

Success · ulong

  • TN_VM_SYSCALL_SUCCESS (0) - Account compressed successfully
  • 0 (special case) - Ephemeral account deleted instead of compressed

Error Codes · ulong

  • TN_VM_ERR_SYSCALL_INVALID_ACCOUNT_INDEX (-8) - Account index out of bounds
  • TN_VM_ERR_SYSCALL_ACCOUNT_DOES_NOT_EXIST (-9) - Account does not exist
  • TN_VM_ERR_SYSCALL_ACCOUNT_NOT_WRITABLE (-10) - Account not writable in transaction
  • TN_VM_ERR_SYSCALL_TXN_HAS_COMPRESSED_ACCOUNT (-37) - Transaction already has a compressed account
  • TN_VM_ERR_SYSCALL_ACCOUNT_COMPRESSION_NOT_ALLOWED (-43) - Account compression is not allowed
  • TN_VM_ERR_SYSCALL_ACCOUNT_UNCOMPRESSABLE (-45) - Account cannot be compressed
  • TN_VM_ERR_SYSCALL_INVALID_PROOF_LEN (-32) - Proof size mismatch
  • TN_VM_ERR_SYSCALL_INVALID_PROOF_SLOT (-33) - Proof references invalid block slot
  • TN_VM_ERR_SYSCALL_INVALID_STATE_PROOF (-23) - State proof verification failed
  • TN_VM_ERR_SYSCALL_STATE_BYTES_REMOVED_OVERFLOW (-48) - State bytes counter overflow during deactivation
  • TN_VM_ERR_SYSCALL_PROGRAM_IN_CALL_STACK (-49) - Cannot compress a program that is currently executing
  • Base cost: TN_VM_SYSCALL_BASE_COST (512 units)
  • Proof cost: Additional units equal to proof size in bytes
  • Data cost: Additional units equal to account data size in bytes
  • Metadata cost: Additional units equal to sizeof(tsdk_account_meta_t)
  • Total formula: base_cost + proof_sz + account_data_sz + sizeof(tsdk_account_meta_t)
  • Page usage: No immediate page deallocation (compression is logical)
  • Proof storage: Temporary memory for proof verification
  • Metadata impact: Account metadata becomes writable if not already
  • GDSC (Global Deactivated State Counter): Incremented by TSDK_ACCOUNT_META_FOOTPRINT + account_data_sz bytes
  • Purpose: Tracks deactivated state for the account compression in the global state counter
  • Overflow protection: Returns TN_VM_ERR_SYSCALL_STATE_BYTES_REMOVED_OVERFLOW if counter would overflow
  • GASC/GDSC check: Compression may be denied if state counter conditions are not met (unless owner/fee payer is compressing)
  • Account state: Sets the COMPRESSED flag
  • State accounting: Adds the account metadata and data size to the transaction’s deactivated-state byte total, which is applied to the global counter after successful execution
  • Transaction state: Copies the input proof into the execution context for the internal state-tree update; the proof is not returned to the caller
  • Special handling: Ephemeral and deleted accounts are deleted instead

Ephemeral accounts are simply deleted when “compressed” - they cannot be truly compressed since they don’t persist beyond the transaction.

  • New accounts: Must use TN_STATE_PROOF_TYPE_CREATION proof type
  • Unchanged existing accounts: Can use TN_STATE_PROOF_TYPE_EXISTING when the current account hash matches the previously committed leaf
  • Modified existing accounts: Use TN_STATE_PROOF_TYPE_UPDATING to prove the previous leaf while committing the account’s current hash
  • Proof verification: Must reference valid block slot and verify against state root
  • Only one account can be compressed per transaction
  • The runtime retains the input proof and account details while finalizing the state-tree update
  • Compression state is tracked to prevent multiple compressions
  • Account must be writable in the transaction (signer approval)
  • The input state proof ensures the account state is correctly recorded
  • Compression does not return a new state proof
  • Compressed accounts can later be decompressed with an EXISTING proof requested separately from the query service
  • Program accounts cannot be compressed while they are in the call stack (current program or any caller)
#include <thru-sdk/c/tn_sdk_syscall.h>
// Compress an account with state proof
ulong account_idx = 2;
uchar proof_data[2048];
ulong proof_size = prepare_compression_proof(account_idx, proof_data);
ulong result = tsys_account_compress(account_idx, proof_data, proof_size);
if (result == TN_VM_SYSCALL_SUCCESS) {
// Account compressed successfully
// COMPRESSED flag set
// Deactivated-state byte accounting updated
// The return value is a status code, not a new state proof
}