Skip to content

feat(explorerextensions): per-alkane tx indexes (txs_by_alkane + internal_txs_by_alkane)#8

Open
kungfuflex wants to merge 2 commits into
bitapeslabs:explorer-v9.0.1-rc1-metashrewfrom
kungfuflex:kungfuflex/by-alkane
Open

feat(explorerextensions): per-alkane tx indexes (txs_by_alkane + internal_txs_by_alkane)#8
kungfuflex wants to merge 2 commits into
bitapeslabs:explorer-v9.0.1-rc1-metashrewfrom
kungfuflex:kungfuflex/by-alkane

Conversation

@kungfuflex

Copy link
Copy Markdown
Collaborator

What

Adds a new espo module explorerextensions that maintains two
trace-derived reverse indexes, keyed by alkane id, to power an
etherscan-style account view for an alkane:

  • explorerextensions.txs_by_alkane — transactions whose top-level
    cellpack target
    (depth 0 in the alkanes trace, i.e. the EOA-level
    "to") is the alkane.
  • explorerextensions.internal_txs_by_alkane — transactions that
    reach the alkane via an internal call (call / delegatecall /
    staticcall) at any depth > 0 — the alkanes analog of etherscan
    "internal txns". Each row carries the internal call frames
    (call_type + caller).

Params for both: { alkane: "block:tx", page?, limit? } (1-indexed page,
default limit 50, cap 500). Results are newest-first and paginated.

Why

There was no alkane-id-keyed index for transaction history at all. The
essentials.get_alkane_balance_txs* methods cover balance-changing
activity, but not "what txs targeted this alkane" or "what txs touched it
internally" — which is exactly what an explorer/wallet needs to render a
contract page like etherscan's Transactions / Internal Txns tabs.

How

Both indexes are derived purely from the alkanes execution trace already
attached to every EspoBlock transaction
, so indexing needs no extra
metashrew calls. index_block walks each trace's event stream with a
depth stack (same shape as extract_alkane_storage): the outermost
Invoke.myself is the top-level target; anything entered at depth > 0 is
an internal call.

  • Storage: standard module Mdb (RocksDB), keyed
    <tag><block:4 BE><tx:8 BE><height:4 BE><txid:32> so a prefix scan
    returns an alkane's whole history in order; values are borsh metadata
    (vout/status/opcode for top-level; call frames for internal).
  • The explorerextensions: namespace is added to the versioned set in
    mdb.rs, so it inherits the same tree-db reorg rollback as the other
    modules (and falls back to plain RocksDB in unit tests, where the global
    tree-db is unset).
  • Registered after essentials in main.rs; no config section required.

Tests

src/modules/explorerextensions/tests.rs — hermetic unit tests
(synthetic traces, temp RocksDB, no metashrew/network) proving:

  • top-level vs internal separation (an alkane delegatecalled internally
    shows up in internal_txs_by_alkane, not txs_by_alkane);
  • status / opcode / caller decoding;
  • idempotent re-indexing (height gate, no duplicate rows).

Verified locally: cargo test --lib explorerextensions → 2 passed.

Note: to run the build locally I had to temporarily pin the alkanes-rs
git deps to the last pre-"v3-align" commit
(b9a8a9f), because as of today alkanes-rs@develop moved the
metashrew-* crates out into kungfuflex/metashrew (they're now in the
workspace exclude list), so metashrew-support = { git = alkanes-rs, branch = "develop" } no longer resolves. That pin is not part of
this PR (deps are left on branch = "develop"); flagging it separately
since it currently blocks espo's build against develop regardless of
this change.

kungfuflex and others added 2 commits June 28, 2026 17:09
Add a new module 'explorerextensions' that maintains two trace-derived
reverse indexes, keyed by alkane id, to power an etherscan-style account
view for an alkane:

  * explorerextensions.txs_by_alkane — transactions whose top-level
    cellpack target (depth 0 in the alkanes trace, i.e. the EOA-level
    'to') is the alkane.
  * explorerextensions.internal_txs_by_alkane — transactions that reach
    the alkane via an internal call (call/delegatecall/staticcall) at any
    depth > 0, the alkanes analog of etherscan 'internal txns'. Each row
    carries the internal call frames (call_type + caller).

Both indexes are derived purely from the alkanes execution trace already
attached to every EspoBlock transaction, so indexing needs no extra
metashrew calls. Storage is the standard module RocksDB (Mdb), keyed
<tag><block:4><tx:8><height:4><txid:32> so a prefix scan returns an
alkane's whole history; the namespace is added to the versioned set so it
inherits tree-db reorg rollback. RPC params: { alkane: 'block:tx',
page?, limit? }; results are newest-first and paginated.

Includes hermetic unit tests (synthetic traces, temp RocksDB, no
metashrew) proving top-level vs internal separation, status/opcode/caller
decoding, and idempotent re-indexing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hrew

alkanes-rs@develop's v3-align restructure moved the metashrew core crates
out of the alkanes-rs workspace (they're now in its 'exclude' list) and
re-sources them from kungfuflex/metashrew (v10, develop). espo still
pointed metashrew-support / metashrew-core / metashrew-runtime /
rockshrew-runtime at alkanes-rs, so those packages no longer resolve and
the whole crate fails to build against current develop:

    error: no matching package named `metashrew-support` found
    location searched: Git repository .../alkanes-rs?branch=develop

Repoint those four deps (incl. the metashrew-core dev-dependency) at
https://github.com/kungfuflex/metashrew (branch develop), mirroring what
alkanes-rs@develop itself now does so the metashrew crates unify to a
single source. Builds clean against current alkanes-rs@develop (77d59aa6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant