rApp: WASM Application Framework

Overview

Reality Network enables developers to deploy WebAssembly (WASM) applications within a blockchain environment, combining the flexibility of WASM with blockchain's consensus and data integrity guarantees. This framework allows you to run custom logic while maintaining deterministic execution across the network.

Architecture

Two-Layer Design

The network operates on two layers:

  • L0 (Layer 0): The permanent ledger layer that stores transaction hashes and maintains the blockchain's immutable history
  • L1 (Layer 1): The application layer where WASM programs execute and participate in consensus

WASM Program Configuration

WASM programs are configured using WasmExecutionParams, which defines how your program interacts with the network:

case class WasmExecutionParams[T, R](
  wasmPath: String,         // Path to your WASM binary
  functionName: String,     // Entry point function name
  paramsConverter: T => Array[Val],  // Convert input to WASM format
  resultConverter: Array[Val] => R,  // Convert WASM output to result type
  serializeToJson: R => Json,        // Convert result to JSON
  paramsDecoder: Decoder[T]          // Parse input parameters
)

Implementation Example

WASM Program

Here's a simple example of a WASM program written in Rust that adds two numbers:

#[no_mangle]
pub extern "C" fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}

The #[no_mangle] attribute and extern "C" ensure the function name is preserved in the WASM binary and follows C calling conventions, making it accessible from our framework.

Framework Configuration

Configure the framework to use your WASM program:

case class AddParams(a: Int, b: Int)

val wasmProgram = WasmExecutionParams(
  wasmPath = "/app/wasm/wasm_add.wasm",
  functionName = "add_numbers",
  paramsConverter = { params: AddParams =>
    Array(Val.fromI32(params.a), Val.fromI32(params.b))
  },
  resultConverter = { vals =>
    vals.headOption.map(_.i32()).getOrElse(0)
  },
  serializeToJson = { result =>
    Json.obj("result" -> Json.fromInt(result))
  },
  paramsDecoder = Decoder[AddParams]
)

Execution Flow

1. Request Submission

To execute a WASM function, clients submit signed requests containing:

  • Function name to execute
  • Input parameters as JSON
  • Required transaction data

We provide client libraries to simplify the construction and signing of these requests. Please refer to our SDK documentation for details.

2. Validation Process

The system performs multiple validation steps:

  • Signature verification
  • Parameter validation
  • Hash verification
  • Transaction validation

3. Execution Queue

Valid requests enter a processing queue where:

  • Nodes maintain queues of pending executions
  • Requests are processed in order
  • Programs are matched to function names

4. WASM Execution

The program executes in an isolated environment:

  • Parameters are converted to WASM format
  • Function is executed
  • Results are converted and serialized

5. Consensus Processing

Results feed into the consensus process:

  • Execution output is processed
  • Result hashes are generated
  • Blocks are formed and validated
  • Results are submitted to L0

6. Data Storage

  • Result hashes are stored on the L0 ledger
  • Raw data can be stored off-chain through consensus process

Error Handling

The framework provides comprehensive error handling:

abstract class WasmError extends Exception {
  def message: String
}

case class FunctionNotFound(functionName: String) extends WasmError
case class ExecutionError(details: String) extends WasmError
case object WasmExecutorUnavailable extends WasmError

Security Considerations

Execution Environment

  • WASM programs run in isolated environments
  • Resource usage is monitored and limited
  • State is isolated between executions

Request Validation

  • Multiple signature validations
  • Transaction linking
  • Hash verification
  • Consensus-based validation

Best Practices

  1. Input Validation

    • Implement thorough parameter validation
    • Handle edge cases in converters
    • Provide clear error messages
  2. Resource Management

    • Optimize WASM binary size
    • Manage memory efficiently
    • Consider computation costs
  3. Error Handling

    • Implement proper error recovery
    • Log relevant error information
    • Provide meaningful error messages
  4. Data Management

    • Plan data storage strategy
    • Consider data size implications
    • Implement efficient data structures

Development Workflow

  1. Development

    • Write your application logic
    • Compile to WASM
    • Configure WasmExecutionParams
  2. Testing

    • Test locally with provided tools
    • Verify parameter conversion
    • Check error handling

Research Initiatives

We are actively exploring several potential enhancements to the framework:

  • Investigating IPFS integration for decentralized data storage at L1
  • Exploring ZKWASM technology for verifiable computation
  • Evaluating additional data availability solutions

Was this page helpful?