Skip to content

Latest commit

 

History

History
83 lines (63 loc) · 3.24 KB

README.org

File metadata and controls

83 lines (63 loc) · 3.24 KB

Maps and folds over Cardano blockchain

Indexers

Indexers:
  addressbalance           Index balance changes for a set of addresses
  addressdatum             Index datums for addresses
  blockbasics              Index slot number, block header hash and number of
                           transactions per block
  deposit                  Index deposits for a set of addresses
  datum                    Index datums by hash
  epochnonce               Index epoch numbers and epoch nonces
  epochstakepoolsize       Index stakepool sizes (in ADA) per epoch
  mamba                    All mamba indexers
  mintburn                 Index minting and burning of custom assets
  noop                     Don't index anything, but drain blocks over local
                           chainsync to measure speed ceiling
  scripttx                 Index transactions with scripts
  utxo                     Index transaction outputs
  intrablockspends         Report the number of intra-block spends: where
                           transaction spends UTxOs from the same block it
                           itself is in.

(Running mafoc with no arguments outputs the above list.)

Run any of the above, e.g the blockbasics indexer:

nix develop # Need to enter nix shell currently

cabal run mafoc:exe:mafoc -- blockbasics \
      --socket-path /home/markus/mainnet/socket/node.socket \
      --mainnet \
      --security-param 2160 \
      --batch-size 50000

By default this will create an sqlite database default.db with an indexer-specific table, often with the indexer’s own name, i.e blockbasics in the above case.

You can tune parameters such as --batch-size (persist to disk) and --pipeline-size (read from chainsync) to try to make it go faster.

Why does this exist?

  • indexer framework that is as simple as possible but no simpler
  • model the indexer as an explicit fold. Fold has a state (indexer dependent) and a sequence of elements it consumes (blocks). It also produces events (“what the business needs”)
  • Using fold as conceptual model will make implementation simple. It will also be familiar to use for external developers.
  • Composable: compose larger indexers from more specific ones, perhaps even mechanically if all turns out well. :)
  • Keep orthogonal things orthogonal, “what business needs” doesn’t have anything to do with the fold state, which is required for checkpointing and resuming.

Framework

Any indexer should implement the Indexer type class which specifies:

  1. toEvents: extract evevnts (“what business needs”) from the block;
  2. persistMany: persist events;
  3. initialize: turn input configuration into runtime configuration (i.e how to turn cli arguments to a reader environment);
  4. checkpoint: store indexer state (the “fold state”). The state and its chainpoint are the only things required to resume an indexer.

The parameter for the Indexer type class instance is the name (“tag”) of the indexer. It also doubles as input configuration (usually read from cli).

For an examlple, see how the blockbasics indexer is implemented.