oasisprotocol / nexus

Official indexer for the Oasis Network.
Apache License 2.0
13 stars 4 forks source link

analyzer: parse emerald genesis #173

Open mitjat opened 1 year ago

mitjat commented 1 year ago

We currently only parse and index the consensus genesis document.

Background on how runtime genesis is stored: At the SDK level, each paratime's genesis_state() is called only once; then each module is responsible for writing its own data in init_or_migrate(). For example, the accounts module delegates to its init() method, which just writes to MKVS. There are no events emitted, no associated txs.

So parsing the emerald genesis is trickier because there is no neat API to retrieve "the genesis document". Instead, we have to:

Alternatively, since genesis only happens once, and since the relevant part of genesis state applied by Emerald is tiny or maybe even empty (!) (no initial balances are created), we can simply manually transcode the genesis into a SQL file, and execute it from the analyzer before processing blocks.

We should almost certainly do the latter. Marking as P2 because although genesis parsing is a blocker to launching emerald Explorer, the genesis sql will likely be empty.

kostko commented 1 year ago

The above is actually incorrect. Genesis will usually be empty (e.g. state root will be equal to the empty root) and will only be initialized in a later block when the runtime is activated as the block needs to be produced by the compute nodes.

We can add an event to identify such a block or you could scan until you get a non-empty root.

mitjat commented 1 year ago

Interesting, thank you. That "activate runtime" block (is that where init() of each SDK module runs?) can do pretty much anything with the state, right? It's just Rust code that directly modifies the state.

If so, having an event that identifies this block won't be all that helpful because the state changes will still be mostly opaque to the indexer. We could strongly encourage runtime developers (and initially, that's only us anyway) to emit events from the init() that correspond to changes performed in init(), if any. Is that feasible?

mitjat commented 1 year ago

https://app.clickup.com/t/3u9yp4x

mitjat commented 1 year ago

Relabeling p3 because of how far/hypothetical this is for now (and the fact that we can deal with one-offs with manual hacks, if needed)

mitjat commented 1 year ago

will only be initialized in a later block when the runtime is activated

@kostko for the current runtimes (emerald, sapphire, cipher), does this "later block" set up any initial balances, or can we ignore it from the perspective of balance tracking? If non-zero balances were included in this block, would they be represented by events, or would it just be a raw update of the state tree?

kostko commented 1 year ago

None of the current runtimes had any initial balances as all tokens needed to be moved over from the consensus layer.