You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|`cid`| Yes | IPFS CID (`Qm...` or `bafy...`). The mock ignores hash/content relationship |
492
+
|`content`| One of `content`/`file`| Inline UTF-8 content |
493
+
|`file`| One of `content`/`file`| File path, resolved relative to the test JSON |
494
+
495
+
### Arweave Files
496
+
497
+
```json
498
+
{
499
+
"name": "Arweave data source test",
500
+
"arweaveFiles": [
501
+
{
502
+
"txId": "abc123",
503
+
"content": "{\"name\": \"Token\"}"
504
+
},
505
+
{
506
+
"txId": "def456/metadata.json",
507
+
"file": "fixtures/arweave-data.json"
508
+
}
509
+
],
510
+
"blocks": [...],
511
+
"assertions": [...]
512
+
}
513
+
```
514
+
515
+
#### arweaveFiles Fields
516
+
517
+
| Field | Required | Description |
518
+
|-------|----------|-------------|
519
+
|`txId`| Yes | Arweave transaction ID or bundle path (e.g. `"txid/filename.json"`) |
520
+
|`content`| One of `content`/`file`| Inline UTF-8 content |
521
+
|`file`| One of `content`/`file`| File path, resolved relative to the test JSON |
522
+
417
523
## Assertions
418
524
419
525
GraphQL queries to validate the indexed entity state after processing all blocks.
@@ -647,10 +753,12 @@ my-subgraph/
647
753
|---------|--------|
648
754
| Log events | ✅ Supported |
649
755
| Block handlers (all filters) | ✅ Supported |
650
-
| eth_call mocking | ✅ Supported |
756
+
|`eth_call` mocking | ✅ Supported |
757
+
|`ethereum.getBalance()` mocking | ✅ Supported |
758
+
|`ethereum.hasCode()` mocking | ✅ Supported |
651
759
| Dynamic/template data sources | ✅ Supported |
652
760
| Transaction receipts (`receipt: true`) | ⚠️ Partial — `receipt.logs` is populated and grouped by `txHash`; other fields (gas, from, to, etc.) are hardcoded stubs (see [Transaction Receipts](#transaction-receipts)) |
653
-
| File data sources / IPFS mocking | ❌ Not implemented|
761
+
| File data sources (IPFS + Arweave) | ✅ Supported|
654
762
| Call triggers (traces) | ❌ Not implemented |
655
763
|`--json` CI output | ❌ Not implemented |
656
764
| Parallel test execution | ❌ Not implemented |
@@ -764,10 +872,8 @@ GraphQL queries → Assertions
764
872
**Key design principles:**
765
873
766
874
-**Isolated database per test:** Each test gets a pgtemp database dropped on completion (default), or a shared persistent database with post-test cleanup (`--postgres-url`)
767
-
-**Real WASM runtime:** Uses `EthereumRuntimeAdapterBuilder` with real `ethereum.call` host function
768
-
-**Pre-populated call cache:**`eth_call` responses are cached before indexing starts
875
+
-**Mock transport layer:** A mock Alloy transport serves `eth_call`, `eth_getBalance`, and `eth_getCode` from test JSON data. All three flow through the real production code path — only the transport returns mock responses. Unmocked RPC calls fail immediately with a descriptive error.
769
876
-**No IPFS for manifest:** Uses `FileLinkResolver` to load manifest/WASM from build directory
770
-
-**Dummy RPC adapter:** Registered at `http://0.0.0.0:0` — exists so the runtime can resolve an adapter with the required capabilities. If a mapping makes an `ethereum.call` that has no matching mock in `ethCalls`, the call misses the cache and falls through to this dummy adapter. The connection is refused immediately (port 0 is invalid), which graph-node treats as a possible reorg and restarts the block stream. The indexer then loops until the 60-second test timeout. See [Unmocked eth_call](#unmocked-eth_call-causes-60-second-timeout) in Troubleshooting.
**Cause:** Call cache miss — no matching mock in `ethCalls`.
796
-
797
-
**Fix:**
798
-
1. Verify `address`, `function`, and `params` exactly match the call from your mapping
799
-
2. Check function signature format: `"functionName(inputTypes)(returnTypes)"`
800
-
3. Ensure parameters are in correct order
801
-
802
-
### Unmocked eth_call Causes 60-Second Timeout
899
+
### Unmocked RPC Call
803
900
804
-
**Cause:** A mapping handler calls `ethereum.call` (directly or via a generated contract binding) for a call that has no matching entry in `ethCalls`. The call misses the pre-populated cache and is forwarded to the dummy RPC adapter at `http://0.0.0.0:0`. The connection is refused immediately, but graph-node interprets connection errors as a possible chain reorganisation and restarts the block stream instead of failing. The indexer loops indefinitely until the test runner's 60-second timeout expires.
901
+
**Cause:** A mapping handler calls `ethereum.call`, `ethereum.getBalance`, or `ethereum.hasCode`for a call that has no matching mock entry.
805
902
806
-
**Symptom:** Test fails with `Sync timeout after 60s` with no indication of which call was missing.
903
+
**Symptom:** Test fails immediately with a descriptive error like:
904
+
```
905
+
gnd test: unmocked eth_call to 0x1234... at block hash 0xabcd...
906
+
Add a matching 'ethCalls' entry to this block in your test JSON.
907
+
```
807
908
808
909
**Fix:**
809
-
1. Add the missing call to `ethCalls` in your test block:
810
-
```json
811
-
"ethCalls": [
812
-
{
813
-
"address": "0xContractAddress",
814
-
"function": "myFunction(uint256):(address)",
815
-
"params": ["42"],
816
-
"returns": ["0xSomeAddress"]
817
-
}
818
-
]
819
-
```
820
-
2. If the call is not supposed to happen, check the mapping logic — a code path may be executing unexpectedly.
821
-
822
-
**Known limitation:** There is currently no fail-fast error for unmocked calls. The only signal is the timeout. A future improvement will make the dummy adapter panic immediately on a cache miss with a descriptive message.
910
+
1. Add the missing mock to the appropriate field in your test block (`ethCalls`, `getBalanceCalls`, or `hasCodeCalls`)
911
+
2. If the call is not supposed to happen, check the mapping logic — a code path may be executing unexpectedly
0 commit comments