What is MODE?

MODE is an off-chain indexer for on-chain applications build with MUD V2. MODE uses PostgresDB as the underlying storage backend and works out-of-the-box with any MUD app. It is capable of indexing MUD applications on any EVM-compatible chain and can index multiple worlds per-chain. It is built primarily as a utility for synchronizing MUD clients to the table state on-chain (see Store for more details) and exposes an API for a client to download MUD app state as well as to stream incremental updates to that state.

Why MODE?

When building any applications, we care about reading and writing data. Writes express a desire to change stuff, while reads express a desire to know “what’s going on”, i.e. retrieve information. When building on-chain apps, modifications are tightly associated with transactions. Transactions are what modify the state. Transactions express user intent, preference, agency, etc. Reads with on-chain apps are more tricky. What does it mean to be able to query the Ethereum network? Technically, given a node with a fully synced state, we can explore just about everything using the EVM, but the “exploring” would be looking at raw storage slots for accounts corresponding to smart contracts. A way around this exists by providing view functions on smart contracts: these effectively are just wrappers around raw storage and expose a more friendly API. Instead of having to figure out where the balances for an account are stored in the storage tree, we now can call a function that does the lookup via Solidity via an RPC endpoint.

The issue with view functions is that complexity in having to generate and call these to get the “full picture” of the state from the chain explodes pretty quickly. For a web app client wanting to present the user with an up-to-date view of the on-chain state, the task of calling the different view functions becomes unnecessarily hard very fast. This can also quickly accelerate the need to run a set of dedicated nodes just to be able to service the needed number of RPC requests.

Applications built with MUD are some of the biggest and most complex on-chain apps out there, so naturally they suffer from the above issues. MODE is one solution to the issue of easy “reads” of on-chain state. MODE is able to “track” the state of any MUD-built application on any network that MODE is running connected to, without having to write any code. Once the state is tracked, parsed, and saved to the underlying storage layer, MODE exposes an API that allows clients to make a single RPC call to retrieve the entire current state. Since after this “read”, there are bound to be more “writes” (e.g. users keep sending transactions to interact with the MUD app), MODE exposes a different endpoint that can stream incremental updates to the on-chain state. This way the client syncs itself once with the full state and maintains in-sync by receiving every change to the state as it happens on-chain and is tracked by MODE.

TODO: add a paragraph about being able to query the state (either on the DB directly or with the DSL)

TODO: add a paragraph comparing MODE to: 1) the snapshot service of MUD1 2) The Graph

MODE Architecture

MODE is designed to be modular and extensible. At a high level, MODE is broken down into the following functions

Below chart roughly sketches out how MODE operates

mode high level.png

Postgres

MODE uses Postgres as the storage backend. This corresponds rather nicely with the way data is stored in MUD V2 and was the initial inspiration for the on-chain data layout design. We realized that data stored this way can leverage a lot from the DB world, therefore using Postgres as the DB was an intuitive choice. MODE saves every table it indexes from the chain into the Postgres database that is provided as a configuration parameter to MODE as start-up.

A single running instance of MODE is able to index multiple chains (networks) and worlds (MUD applications). Since this means a large amount of tables per-world and per-chain, MODE uses Postgres schemas to separate the tables and the corresponding data. Schemas are sort of like namespaces or folders. They allow us to better organize the database if we have a lot of tables. MODE operates on three levels of namespacing with schemas

  1. MODE namespace — mode (internal MODE operational tables only)
  2. Chain namespace (e.g. mode_1 for Ethereum mainnet or mode_371337 for hardhat network)