Architecture
Tensora's architecture combines three layers: the OP Stack rollup infrastructure, BNB Chain settlement, and the AI subnet protocol. This page explains how transactions flow from user submission to L1 finalization, and how AI workloads integrate with the EVM.
System Components
Copy
flowchart TB
subgraph Users
Wallet[Wallet / dApp]
end
subgraph Tensora L2
Sequencer[Sequencer Node]
Paymaster[ToraPaymaster]
Execution[Execution Engine]
Subnets[Subnet Contracts]
Miners[Miner Nodes]
Validators[Validator Nodes]
end
subgraph Infrastructure
Batcher[Batcher Service]
Proposer[Proposer Service]
end
subgraph BNB Chain L1
DA[Calldata Storage]
Bridge[L1StandardBridge]
PropContract[L2OutputOracle]
end
Wallet -->|UserOp with TORA| Paymaster
Paymaster -->|Pays BNB| Sequencer
Sequencer --> Execution
Execution --> Subnets
Subnets <--> Miners
Subnets <--> Validators
Sequencer -->|Raw txs| Batcher
Batcher -->|Compressed batches| DA
Execution -->|State| Proposer
Proposer -->|State root + proof| PropContract
Wallet <-->|Deposit/Withdraw| Bridge
Bridge <--> PropContractTransaction Lifecycle
User Submits Transaction
A user signs a transaction or UserOperation with their wallet. If using ERC-4337, the op is sent to a bundler. Otherwise, it's a standard Ethereum transaction.
Gas Payment: The user specifies a maxFeePerGas in TORA. The ToraPaymaster intercepts the call, checks TORA balance, and pays the sequencer in BNB.
Sequencer Orders and Executes
The sequencer:
Validates signature and nonce
Checks gas limits
Orders the transaction in the next L2 block
Executes it in the EVM (geth fork)
Emits a soft confirmation (unfinalized)
The sequencer runs a modified op-geth node. It uses BNB as the native gas token internally but accepts TORA via the Paymaster.
Batcher Compresses and Posts
The batcher service:
Collects raw transactions from the sequencer
Compresses them (zlib or brotli)
Posts the batch as calldata to a BSC contract
This happens every ~10 minutes or when a size threshold is reached. The calldata becomes the canonical data availability layer.
Proposer Submits State Root
The proposer service:
Computes the L2 state root after executing batches
Signs a commitment
Submits it to the
L2OutputOraclecontract on BSC
State roots are posted every ~1 hour. They serve as checkpoints for withdrawal finalization and fraud proofs (when enabled).
L1 Finalization
After the challenge period (7 days), withdrawals using that state root become executable on BSC. Deposits are considered final when their BSC transaction has sufficient confirmations (~15 blocks, ~45 seconds).
Gas Model Explained
Internal: BNB as Native Gas
The OP Stack execution engine expects ETH (or BNB) as the native token. Gas metering, opcodes like BALANCE and CALL, and refunds all use BNB.
Why? This avoids forking the EVM gas metering logic. BNB is chosen because Tensora settles on BSC, making BNB acquisition straightforward for infrastructure operators.
User-Facing: TORA via Paymaster
End users never hold BNB. Instead:
User calls
validatePaymasterUserOpinToraPaymasterPaymaster checks user's TORA balance (
ToraToken.balanceOf)Paymaster pays sequencer in BNB (
transferto sequencer address)Paymaster debits user's TORA (
ToraToken.transferFrom)Transaction executes as normal
Exchange Rate: The Paymaster uses a BNB/TORA price oracle (Chainlink or TWAP) to calculate the TORA deduction. A small fee (e.g., 2%) covers Paymaster operational costs.
Fallback: If Paymaster fails (e.g., out of BNB), the sequencer rejects the UserOperation. Users can still send raw transactions with BNB gas if they hold BNB, but this is not the intended UX.
Data Availability Deep Dive
Why Calldata on BSC?
Cost: BSC calldata is ~10× cheaper than Ethereum mainnet calldata.
Availability: BSC has ~70 validators with public archives. Data is replicated and queryable.
Compatibility: OP Stack batcher is designed for EVM calldata. No custom DA adapter needed.
Trade-off: Less decentralized than Ethereum. Acceptable for an AI L2 where cost and speed are priorities.
Batch Structure
Each batch is a byte array containing:
Version byte
Block count (varint)
For each block:
Timestamp (varint)
Transaction count (varint)
RLP-encoded transactions
Compression is applied after serialization. The batcher contract on BSC emits an event with the batch hash for indexing.
Future Upgrades
BNB Greenfield: Object storage DA with erasure coding
EigenDA: Ethereum-aligned DA layer
Celestia: Modular DA with light clients
Migration requires a hard fork and coordination with the proposer.
Bridge Contract Flow
Deposit (L1 → L2)
Copy
// On BSC (L1)
L1StandardBridge.depositERC20(
address _l1Token, // WTORA address on BSC
address _l2Token, // TORA address on Tensora
uint256 _amount,
uint32 _l2Gas,
bytes calldata _data
)User approves
L1StandardBridgeto spend WTORABridge locks WTORA in escrow
Bridge calls
L1CrossDomainMessenger.sendMessageMessage relayer picks up event, submits to L2
L2StandardBridgemints TORA to user's L2 address
Finality: L2 minting happens after the BSC tx has 15 confirmations (~45 seconds).
Withdrawal (L2 → L1)
Copy
// On Tensora (L2)
L2StandardBridge.withdraw(
address _l2Token, // TORA
uint256 _amount,
uint32 _l1Gas,
bytes calldata _data
)User calls withdraw, L2 burns TORA
Withdrawal is included in a batch, posted to BSC
Proposer includes withdrawal in a state root
After 7-day challenge period, user calls
finalizeWithdrawalon L1L1StandardBridgereleases WTORA from escrow to user
Challenge Window: 7 days allows fraud proofs to dispute invalid withdrawals. No fraud proof system is live initially; guardian multi-sig can pause withdrawals manually.
Fee-on-Transfer Token Handling
The underlying Four.meme token has a transfer tax (e.g., 1% burned on transfer). Bridging it directly would cause mismatch:
User deposits 100 tokens
Bridge receives 99 tokens (1 burned)
L2 mints 100 tokens
User withdraws 100 tokens
L1 releases 99 tokens (shortfall)
Solution: Bridge only WTORA, a wrapper with no transfer tax. Users wrap Four.meme → WTORA on BSC before bridging.
AI Subnet Architecture
Off-Chain Inference, On-Chain Scoring
Miners run inference servers (HTTP APIs or P2P). Validators send tasks off-chain, receive responses, and submit scores on-chain via the SubnetRegistry contract.
Copy
sequenceDiagram
participant Validator
participant Miner
participant SubnetContract
participant EmissionManager
Validator->>Miner: HTTP POST /infer {task}
Miner->>Validator: {result, signature}
Validator->>SubnetContract: submitScore(minerId, score, commitment)
Note over SubnetContract: Commit-reveal phase
Validator->>SubnetContract: revealScore(minerId, score, salt)
SubnetContract->>SubnetContract: aggregateScores (Yuma)
SubnetContract->>EmissionManager: claimRewards(epoch)
EmissionManager->>Validator: transfer TORA (41%)
EmissionManager->>Miner: transfer TORA (18%)Consensus Without L2 Fork Choice
Tensora uses a single sequencer, so there are no L2 forks. Yuma consensus is purely economic: it ranks miners by quality, not by choosing between blockchain branches.
Commit-Reveal Timeline:
Epoch N block 0–1000: validators query miners, compute scores
Block 1001–1050: validators commit
hash(scores + salt)Block 1051–1100: validators reveal
(scores, salt)Block 1101: contract aggregates, updates weights
Block 1102+: rewards claimable
Subnet Isolation
Each subnet is a separate contract instance deployed via SubnetFactory. Subnets have independent:
Miner registries
Validator stake pools
Hyperparameters (task timeout, min stake, slashing rate)
Emission weights (set by governance)
A bug in Subnet A's scoring logic does not affect Subnet B. However, slashing in Subnet A reduces a validator's global trust score, indirectly affecting their weight in Subnet B.
Sequencer and Decentralization Roadmap
Current: Single Sequencer
Tensora Labs operates the sequencer. Censorship resistance comes from the OP Stack's forced inclusion mechanism: users can submit transactions directly to the L1 bridge contract, and the sequencer must include them or risk losing the proposer bond.
Future: Shared Sequencing
Options under consideration:
Espresso: Decentralized sequencer network with HotShot consensus
Radius: Encrypted mempool with threshold decryption
Astria: Shared sequencer for multiple rollups
Migration requires updating the batcher and proposer to coordinate with the external sequencer network.
Upgradeability and Governance
All protocol contracts use UUPS proxies. The ToraGovernor contract can propose upgrades, which must pass:
On-chain vote (quorum + approval threshold)
Timelock delay (e.g., 48 hours)
Execution by
UpgradeManager
Storage Safety: Before upgrading, developers run:
Copy
forge inspect --storage-layout OldContract > old.json
forge inspect --storage-layout NewContract > new.json
diff old.json new.jsonInserting variables above existing ones breaks storage. Use storage gaps (uint256[50] __gap) to reserve slots.
State Trie and Execution
Tensora uses the same state trie structure as Ethereum (modified Merkle-Patricia trie). State roots are Keccak hashes of account data (nonce, balance, storageRoot, codeHash).
State Growth: With high subnet activity, state can grow large. Archive nodes store full history. Full nodes prune old states, keeping only recent checkpoints.
Reorgs: The sequencer does not reorg. L1 reorgs on BSC (rare, <1 per month) can invalidate L2 state roots, triggering a manual intervention by the guardian multi-sig.
Monitoring and Observability
Sequencer metrics: Block production rate, mempool size, gas usage
Batcher metrics: Batch size, compression ratio, BSC gas cost
Proposer metrics: State root submission interval, L1 confirmation time
Paymaster metrics: BNB balance, TORA deductions, failed ops
Subnet metrics: Task throughput, validator uptime, slashing events
Prometheus endpoints are exposed on http://sequencer:9090/metrics, http://batcher:9091/metrics, etc.
Last updated