From bfdd8a3dab25eb7fd056e68a65eb1b4f82e9bb27 Mon Sep 17 00:00:00 2001 From: YaroShkvorets Date: Wed, 30 Apr 2025 16:25:00 -0400 Subject: [PATCH 1/3] fix global wasm vars with one simple trick --- packages/ts/chain/arweave.ts | 1 + packages/ts/chain/cosmos.ts | 1 + packages/ts/chain/ethereum.ts | 1 + packages/ts/chain/near.ts | 1 + packages/ts/chain/starknet.ts | 1 + packages/ts/common/conversion.ts | 1 + packages/ts/common/datasource.ts | 1 + packages/ts/common/eager_offset.ts | 42 ++++++++++++++++++++++++++++++ packages/ts/common/json.ts | 1 + packages/ts/common/numbers.ts | 1 + packages/ts/common/value.ts | 1 + packages/ts/common/yaml.ts | 1 + 12 files changed, 53 insertions(+) create mode 100644 packages/ts/common/eager_offset.ts diff --git a/packages/ts/chain/arweave.ts b/packages/ts/chain/arweave.ts index 966e54140..191da226f 100644 --- a/packages/ts/chain/arweave.ts +++ b/packages/ts/chain/arweave.ts @@ -1,3 +1,4 @@ +import '../common/eager_offset'; import { Bytes } from '../common/collections'; // Most types from this namespace are direct mappings or adaptations from: diff --git a/packages/ts/chain/cosmos.ts b/packages/ts/chain/cosmos.ts index bf2b6579b..96c98dbbb 100644 --- a/packages/ts/chain/cosmos.ts +++ b/packages/ts/chain/cosmos.ts @@ -1,3 +1,4 @@ +import '../common/eager_offset'; import { Bytes } from '../common/collections'; export namespace cosmos { diff --git a/packages/ts/chain/ethereum.ts b/packages/ts/chain/ethereum.ts index de2b97a5e..abd8ce1bf 100644 --- a/packages/ts/chain/ethereum.ts +++ b/packages/ts/chain/ethereum.ts @@ -1,3 +1,4 @@ +import '../common/eager_offset'; import { Bytes, Wrapped } from '../common/collections'; import { Address, BigInt } from '../common/numbers'; diff --git a/packages/ts/chain/near.ts b/packages/ts/chain/near.ts index 1c62ae445..46883a48c 100644 --- a/packages/ts/chain/near.ts +++ b/packages/ts/chain/near.ts @@ -1,3 +1,4 @@ +import '../common/eager_offset'; import { Bytes } from '../common/collections'; import { BigInt } from '../common/numbers'; diff --git a/packages/ts/chain/starknet.ts b/packages/ts/chain/starknet.ts index 881156d59..97f32d6ab 100644 --- a/packages/ts/chain/starknet.ts +++ b/packages/ts/chain/starknet.ts @@ -1,3 +1,4 @@ +import '../common/eager_offset'; import { Bytes } from '../common/collections'; import { BigInt } from '../common/numbers'; diff --git a/packages/ts/common/conversion.ts b/packages/ts/common/conversion.ts index e06bcaeb6..a4b350f78 100644 --- a/packages/ts/common/conversion.ts +++ b/packages/ts/common/conversion.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { Bytes } from './collections'; /** Host type conversion interface */ diff --git a/packages/ts/common/datasource.ts b/packages/ts/common/datasource.ts index b840cb386..cb6dd33c3 100644 --- a/packages/ts/common/datasource.ts +++ b/packages/ts/common/datasource.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { Entity } from './collections'; import { Address } from './numbers'; diff --git a/packages/ts/common/eager_offset.ts b/packages/ts/common/eager_offset.ts new file mode 100644 index 000000000..148f29fa9 --- /dev/null +++ b/packages/ts/common/eager_offset.ts @@ -0,0 +1,42 @@ +// # What is this file? +// This file is a "hack" to allow global variables in subgraphs and +// on this library (`graph-ts`). +// +// # Why is it needed? +// It's necessary because of one of the features of the AssemblyScript +// compiler we use, the stub runtime. +// +// The problem happens because we call the stub runtime allocation +// (`__alloc`) directly on Rust side (`graph-node`), and that doesn't +// trigger some AssemblyScript aspects of the code. +// +// If you take a look at the stub runtime's code, you'll see that the +// `__alloc` function uses a variable named `offset` tagged as `lazy`. +// Like said above, since we call it on Rust side, this variable is not +// "triggered" to be used, then it's declared below the `__alloc` call +// in the compiled WASM code. +// +// That makes the `graph-node` WASM runtime break because of this out +// of order variable usage. +// +// # How does this fix the issue? +// The way this workaround works is by calling the `__alloc` function +// before everything in the AssemblyScript side. This makes the `offset` +// `lazy` variable be eagerly evaluated when the mappings are compiled +// (since they always import `graph-ts`). +// +// So when we're on Rust side calling `__alloc` it will be fine, because +// the `offset` is declared before call (order fixed because of this file). +// +// The 0 argument to the function call is just because we need no memory +// to be allocated. +// +// # IMPORTANT +// This should be imported in EVERY file which uses external namespaces (`graph-node` host-exports code), +// just to make sure no one imports a file directly and gets an error on global variables. +// +// # Reference +// - Runtimes in AS: https://www.assemblyscript.org/garbage-collection.html#runtime-variants +// - `offset` variable in question: https://github.com/AssemblyScript/assemblyscript/blob/f4091b8f3b6b029d30cd917cf84d97421faadeeb/std/assembly/rt/stub.ts#L9 +// @ts-expect-error We do not want to expose __alloc, hence why we just ignore the error +__alloc(0); diff --git a/packages/ts/common/json.ts b/packages/ts/common/json.ts index 3ad66e6a0..12d128dce 100644 --- a/packages/ts/common/json.ts +++ b/packages/ts/common/json.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { Bytes, Result } from './collections'; import { BigInt } from './numbers'; import { JSONValue } from './value'; diff --git a/packages/ts/common/numbers.ts b/packages/ts/common/numbers.ts index 501eb706f..509cf0b6c 100644 --- a/packages/ts/common/numbers.ts +++ b/packages/ts/common/numbers.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { ByteArray, Bytes } from './collections'; import { typeConversion } from './conversion'; diff --git a/packages/ts/common/value.ts b/packages/ts/common/value.ts index 605515ddd..5a5f1e9bb 100644 --- a/packages/ts/common/value.ts +++ b/packages/ts/common/value.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { Bytes, TypedMap } from './collections'; import { json } from './json'; import { Address, BigDecimal, BigInt } from './numbers'; diff --git a/packages/ts/common/yaml.ts b/packages/ts/common/yaml.ts index d3a7ecce7..b1a2500d4 100644 --- a/packages/ts/common/yaml.ts +++ b/packages/ts/common/yaml.ts @@ -1,3 +1,4 @@ +import './eager_offset'; import { Bytes, Result, TypedMap } from './collections'; import { BigInt } from './numbers'; From 6f88965d66f4e6818a3572a1a578e3158b7bf0b3 Mon Sep 17 00:00:00 2001 From: YaroShkvorets Date: Wed, 30 Apr 2025 16:27:47 -0400 Subject: [PATCH 2/3] fix ts tests --- packages/ts/common/yaml.ts | 2 +- packages/ts/test/test.mjs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ts/common/yaml.ts b/packages/ts/common/yaml.ts index b1a2500d4..23635da35 100644 --- a/packages/ts/common/yaml.ts +++ b/packages/ts/common/yaml.ts @@ -295,6 +295,6 @@ export class YAMLTaggedValue { return true; } - return !(a! == b!); + return !(a == b); } } diff --git a/packages/ts/test/test.mjs b/packages/ts/test/test.mjs index dbf4b3dd6..69f07e403 100644 --- a/packages/ts/test/test.mjs +++ b/packages/ts/test/test.mjs @@ -28,6 +28,7 @@ async function main() { fs.copyFileSync('common/collections.ts', 'test/temp_lib/common/collections.ts'); fs.copyFileSync('common/conversion.ts', 'test/temp_lib/common/conversion.ts'); fs.copyFileSync('common/datasource.ts', 'test/temp_lib/common/datasource.ts'); + fs.copyFileSync('common/eager_offset.ts', 'test/temp_lib/common/eager_offset.ts'); fs.copyFileSync('common/json.ts', 'test/temp_lib/common/json.ts'); fs.copyFileSync('common/numbers.ts', 'test/temp_lib/common/numbers.ts'); fs.copyFileSync('common/value.ts', 'test/temp_lib/common/value.ts'); @@ -50,6 +51,7 @@ async function main() { fs.unlinkSync('test/temp_lib/common/collections.ts'); fs.unlinkSync('test/temp_lib/common/conversion.ts'); fs.unlinkSync('test/temp_lib/common/datasource.ts'); + fs.unlinkSync('test/temp_lib/common/eager_offset.ts'); fs.unlinkSync('test/temp_lib/common/json.ts'); fs.unlinkSync('test/temp_lib/common/numbers.ts'); fs.unlinkSync('test/temp_lib/common/value.ts'); From a6488307393a3c59182b0cd33e55af88f293970b Mon Sep 17 00:00:00 2001 From: YaroShkvorets Date: Wed, 30 Apr 2025 16:29:24 -0400 Subject: [PATCH 3/3] changeset --- .changeset/tangy-clowns-thank.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tangy-clowns-thank.md diff --git a/.changeset/tangy-clowns-thank.md b/.changeset/tangy-clowns-thank.md new file mode 100644 index 000000000..2cd28fcb5 --- /dev/null +++ b/.changeset/tangy-clowns-thank.md @@ -0,0 +1,5 @@ +--- +'@graphprotocol/graph-ts': patch +--- + +fix global variables in wasm