diff --git a/README.md b/README.md index d274eb3..420f92f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A Logos Core **service module** (`type: core`, universal authoring model) that runs the Logos Execution Zone (L2) indexer and exposes it to the Logos ecosystem. It is a thin Qt-free plugin around the `indexer_ffi` library from [`logos-execution-zone`](https://github.com/logos-blockchain/logos-execution-zone): it starts the indexer, which connects to an L1/bedrock node and indexes the zone's channel, and exposes **query methods over the Logos protocol** (Qt Remote Objects). -Registered module name: **`lez_indexer_module`**. Its public methods *are* its API — other modules call them in-process over the Logos protocol. It pairs with the +Registered module name: **`lez_indexer_module`**. Its public methods _are_ its API — other modules call them in-process over the Logos protocol. It pairs with the [`lez-explorer-ui`](https://github.com/logos-co/lez-explorer-ui) block explorer, which reads from it **in-process over the Logos protocol** (typed `modules().lez_indexer_module.*` calls) — no RPC endpoint or socket in between. > [!TIP] @@ -50,15 +50,16 @@ On success it returns `0`; a non-zero return is the FFI `OperationStatus` (e.g. Each returns a compact JSON string (an **empty** string means not-found / failed query); all ids/hashes are 32-byte hex, all numeric args/ids are decimal strings. -| Method | Returns | -| --- | --- | -| `getLastFinalizedBlockId()` | tip block id (bare decimal string) | -| `getBlockById(block_id)` | block JSON | -| `getBlockByHash(hash)` | block JSON | -| `getBlocks(before, limit)` | JSON array of blocks; `before` = `""` for the tip, else a block id to page back from | -| `getTransaction(hash)` | transaction JSON | -| `getAccount(account_id)` | account JSON (the payload omits the id; callers inject the queried id) | -| `getTransactionsByAccount(account_id, offset, limit)` | JSON array of transactions touching the account | +| Method | Returns | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------ | +| `getStatus()` | indexer status JSON (schema owned by `indexer_core`) | +| `getLastFinalizedBlockId()` | tip block id (bare decimal string) | +| `getBlockById(block_id)` | block JSON | +| `getBlockByHash(hash)` | block JSON | +| `getBlocks(before, limit)` | JSON array of blocks; `before` = `""` for the tip, else a block id to page back from | +| `getTransaction(hash)` | transaction JSON | +| `getAccount(account_id)` | account JSON (the payload omits the id; callers inject the queried id) | +| `getTransactionsByAccount(account_id, offset, limit)` | JSON array of transactions touching the account | Because the module uses the universal authoring model (`interface: "universal"`), it publishes a typed LIDL contract, so universal consumers get Qt-typed wrappers (`modules().lez_indexer_module.getBlockById(...)`) rather than dynamic by-name calls. @@ -66,10 +67,9 @@ Because the module uses the universal authoring model (`interface: "universal"`) `config/indexer_config.json` is deserialized into the indexer's `IndexerConfig`. Key fields: -| Field | Meaning | Default | -| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `bedrock_config.addr` | L1/bedrock node URL the indexer reads from; it must be reachable. | `http://localhost:8080` | -| `home` | Directory for the indexer's RocksDB state, relative to the host's working directory. Use an absolute path for a predictable location. | `"."` | -| `channel_id` | The zone channel the indexer consumes; must match what the sequencer inscribes. | | +| Field | Meaning | Default | +| --------------------- | ------------------------------------------------------------------------------- | ----------------------- | +| `bedrock_config.addr` | L1/bedrock node URL the indexer reads from; it must be reachable. | `http://localhost:8080` | +| `channel_id` | The zone channel the indexer consumes; must match what the sequencer inscribes. | | The config keys must match the `IndexerConfig` schema of the `logos-execution-zone` rev pinned in `flake.nix`/`flake.lock`; bumping that rev may require re-syncing this file. Unknown keys are ignored. diff --git a/config/indexer_config.json b/config/indexer_config.json index a8ff5cb..72ec53f 100644 --- a/config/indexer_config.json +++ b/config/indexer_config.json @@ -1,160 +1,53 @@ { - "home": ".", - "consensus_info_polling_interval": "1s", - "bedrock_config": { - "addr": "http://localhost:8080", - "backoff": { - "start_delay": "100ms", - "max_retries": 5 - } + "consensus_info_polling_interval": "1s", + "bedrock_config": { + "addr": "http://localhost:8080", + "backoff": { + "start_delay": "100ms", + "max_retries": 5 + } + }, + "channel_id": "0101010101010101010101010101010101010101010101010101010101010101", + "initial_accounts": [ + { + "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r", + "balance": 10000 }, - "channel_id": "0101010101010101010101010101010101010101010101010101010101010101", - "initial_accounts": [ - { - "account_id": "CbgR6tj5kWx5oziiFptM7jMvrQeYY3Mzaao6ciuhSr2r", - "balance": 10000 - }, - { - "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2", - "balance": 20000 - } - ], - "initial_commitments": [ - { - "npk": [ - 139, - 19, - 158, - 11, - 155, - 231, - 85, - 206, - 132, - 228, - 220, - 114, - 145, - 89, - 113, - 156, - 238, - 142, - 242, - 74, - 182, - 91, - 43, - 100, - 6, - 190, - 31, - 15, - 31, - 88, - 96, - 204 - ], - "account": { - "program_owner": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "balance": 10000, - "data": [], - "nonce": 0 - } - }, - { - "npk": [ - 173, - 134, - 33, - 223, - 54, - 226, - 10, - 71, - 215, - 254, - 143, - 172, - 24, - 244, - 243, - 208, - 65, - 112, - 118, - 70, - 217, - 240, - 69, - 100, - 129, - 3, - 121, - 25, - 213, - 132, - 42, - 45 - ], - "account": { - "program_owner": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "balance": 20000, - "data": [], - "nonce": 0 - } - } - ], - "signing_key": [ - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37, - 37 - ] -} \ No newline at end of file + { + "account_id": "2RHZhw9h534Zr3eq2RGhQete2Hh667foECzXPmSkGni2", + "balance": 20000 + } + ], + "initial_commitments": [ + { + "npk": [ + 139, 19, 158, 11, 155, 231, 85, 206, 132, 228, 220, 114, 145, 89, 113, + 156, 238, 142, 242, 74, 182, 91, 43, 100, 6, 190, 31, 15, 31, 88, 96, + 204 + ], + "account": { + "program_owner": [0, 0, 0, 0, 0, 0, 0, 0], + "balance": 10000, + "data": [], + "nonce": 0 + } + }, + { + "npk": [ + 173, 134, 33, 223, 54, 226, 10, 71, 215, 254, 143, 172, 24, 244, 243, + 208, 65, 112, 118, 70, 217, 240, 69, 100, 129, 3, 121, 25, 213, 132, 42, + 45 + ], + "account": { + "program_owner": [0, 0, 0, 0, 0, 0, 0, 0], + "balance": 20000, + "data": [], + "nonce": 0 + } + } + ], + "signing_key": [ + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 + ] +} diff --git a/metadata.json b/metadata.json index cadc543..3a54678 100644 --- a/metadata.json +++ b/metadata.json @@ -8,9 +8,7 @@ "main": "lez_indexer_module_plugin", "dependencies": [], "nix": { - "external_libraries": [ - { "name": "indexer_ffi" } - ], + "external_libraries": [{ "name": "indexer_ffi" }], "cmake": { "extra_include_dirs": ["lib"] } diff --git a/src/lez_indexer_ffi.h b/src/lez_indexer_ffi.h index 0f7b374..8f13ee0 100644 --- a/src/lez_indexer_ffi.h +++ b/src/lez_indexer_ffi.h @@ -1,10 +1,11 @@ #pragma once -// Wrap the generated indexer_ffi.h in `extern "C"` (it is a C header) behind a -// single include point, so both lez_indexer_module_impl.cpp and -// lez_ffi_marshalling share the FFI types with C linkage. indexer_ffi.h now -// carries its own `#pragma once`, so this is purely about linkage + one include -// site (include THIS header, not directly). +// The generated indexer_ffi.h is a plain C header with no `extern "C"` guard of +// its own, so a C++ translation unit including it directly would name-mangle the +// FFI declarations and fail to link against the C-ABI symbols in libindexer_ffi. +// This wrapper provides the `extern "C"` linkage behind a single include point; +// both lez_indexer_module_impl.cpp and lez_ffi_marshalling include THIS header, +// not directly. #ifdef __cplusplus extern "C" { #endif