From 72bfee3e5cb02b24da1060915402f6d1c7385eee Mon Sep 17 00:00:00 2001 From: baku-ccron Date: Tue, 25 Aug 2026 18:45:05 +0000 Subject: [PATCH] Observe nextMetaId across a multi-event, multi-board matchstick run Co-Authored-By: Claude Opus 5 (1M context) --- subgraph/tests/address.ts | 6 ++ subgraph/tests/metaBoard.test.ts | 105 +++++++++++++++++++++++++++++-- subgraph/tests/utils.ts | 6 +- 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/subgraph/tests/address.ts b/subgraph/tests/address.ts index 84c3cf44..6a8956d0 100644 --- a/subgraph/tests/address.ts +++ b/subgraph/tests/address.ts @@ -5,3 +5,9 @@ import { Address } from "@graphprotocol/graph-ts"; export const CONTRACT_ADDRESS = Address.fromString( "0xfb8437AeFBB8031064E274527C5fc08e30Ac6928", ); + +// A second metaboard, for the case one deployment indexes more than one. It +// has no counterpart on any chain; nothing here calls it. +export const OTHER_CONTRACT_ADDRESS = Address.fromString( + "0x4a9b0f6c1e3d2a5b8c7d6e9f0a1b2c3d4e5f6a7b", +); diff --git a/subgraph/tests/metaBoard.test.ts b/subgraph/tests/metaBoard.test.ts index 5717962b..854fb665 100644 --- a/subgraph/tests/metaBoard.test.ts +++ b/subgraph/tests/metaBoard.test.ts @@ -9,11 +9,14 @@ import { newMockEvent, clearInBlockStore, } from "matchstick-as"; -import { createNewMetaV1Event, CONTRACT_ADDRESS } from "./utils"; -import { Bytes, BigInt, ethereum, Address } from "@graphprotocol/graph-ts"; import { - MetaV1_2, -} from "../generated/metaboard0/MetaBoard"; + createNewMetaV1Event, + handleNewMetaV1Events, + CONTRACT_ADDRESS, + OTHER_CONTRACT_ADDRESS, +} from "./utils"; +import { Bytes, BigInt, ethereum, Address } from "@graphprotocol/graph-ts"; +import { MetaV1_2 } from "../generated/metaboard0/MetaBoard"; import { MetaBoard, MetaV1 as MetaV1Entity, @@ -47,6 +50,7 @@ describe("Test meta event", () => { const meta = Bytes.fromHexString(metaString); const newMetaV1Event = createNewMetaV1Event( + CONTRACT_ADDRESS, sender, subject, meta, @@ -180,6 +184,7 @@ describe("Test MetaBoard and MetaV1 Entities", () => { beforeAll(() => { const meta = Bytes.fromHexString(metaString); const newMetaV1Event = createNewMetaV1Event( + CONTRACT_ADDRESS, sender, subject, meta, @@ -258,3 +263,95 @@ describe("Test MetaBoard and MetaV1 Entities", () => { assert.bytesEquals(retrievedTransaction.from, Address.fromString(sender)); }); }); + +const firstCounterTransactionHash = + "0x1111111111111111111111111111111111111111111111111111111111111111"; +const secondCounterTransactionHash = + "0x2222222222222222222222222222222222222222222222222222222222222222"; +const thirdCounterTransactionHash = + "0x3333333333333333333333333333333333333333333333333333333333333333"; + +describe("Test MetaBoard nextMetaId counter", () => { + afterEach(() => { + clearStore(); + clearInBlockStore(); + }); + + test("nextMetaId counts one per meta the board has seen", () => { + handleNewMetaV1Events([ + createNewMetaV1Event( + CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + firstCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + createNewMetaV1Event( + CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + secondCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + createNewMetaV1Event( + CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + thirdCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + ]); + + assert.entityCount(ENTITY_TYPE_META_BOARD, 1); + assert.entityCount(ENTITY_TYPE_META_V1, 3); + + const board = MetaBoard.load(CONTRACT_ADDRESS) as MetaBoard; + assert.bigIntEquals(board.nextMetaId, BigInt.fromI32(3)); + }); + + // Cross-board MetaV1 identity is #206's; this asserts only the counters. + test("Each metaboard counts only its own metas", () => { + handleNewMetaV1Events([ + createNewMetaV1Event( + CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + firstCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + createNewMetaV1Event( + OTHER_CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + secondCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + createNewMetaV1Event( + CONTRACT_ADDRESS, + sender, + subject, + Bytes.fromHexString(metaString), + thirdCounterTransactionHash, + transactionBlockNumber, + transactionTimestamp, + ), + ]); + + assert.entityCount(ENTITY_TYPE_META_BOARD, 2); + + const board = MetaBoard.load(CONTRACT_ADDRESS) as MetaBoard; + const otherBoard = MetaBoard.load(OTHER_CONTRACT_ADDRESS) as MetaBoard; + assert.bigIntEquals(board.nextMetaId, BigInt.fromI32(2)); + assert.bigIntEquals(otherBoard.nextMetaId, BigInt.fromI32(1)); + }); +}); diff --git a/subgraph/tests/utils.ts b/subgraph/tests/utils.ts index 2323ee84..bb752677 100644 --- a/subgraph/tests/utils.ts +++ b/subgraph/tests/utils.ts @@ -2,9 +2,9 @@ import { MetaV1_2 } from "../generated/metaboard0/MetaBoard"; import { ethereum, Address, BigInt, Bytes } from "@graphprotocol/graph-ts"; import { newMockEvent } from "matchstick-as"; import { handleMetaV1_2 } from "../src/metaBoard"; -import { CONTRACT_ADDRESS } from "./address"; export function createNewMetaV1Event( + board: Address, sender: string, subject: Bytes, meta: Bytes, @@ -15,7 +15,7 @@ export function createNewMetaV1Event( // Create a mock ethereum.Event instance const metaV1Event = changetype(newMockEvent()); metaV1Event.parameters = new Array(); - metaV1Event.address = CONTRACT_ADDRESS; + metaV1Event.address = board; // Set up transaction data metaV1Event.transaction.hash = Bytes.fromHexString(transactionHash); @@ -48,4 +48,4 @@ export function handleNewMetaV1Events(events: MetaV1_2[]): void { }); } -export { CONTRACT_ADDRESS } from "./address"; +export { CONTRACT_ADDRESS, OTHER_CONTRACT_ADDRESS } from "./address";