Legacynet Compatible AOS
Legacynet compatible AOS uses genesis-wasm@1.0
to delegate compute to an external local CU. You can use wasm modules stored on the Arweave Mainnet storage, or you could create a helper method to locally store wasm modules for testing. You should also pass as = ["genesis_wasm"]
to the test HyperBEAM node to auto-start a local CU server with HyperBEAM.
Let's use the production AOS2.0.6 module stored at ISShJH1ij-hPPt9St5UFFr_8Ys3Kj5cyg7zrMGt7H9s
for now.
import assert from "assert"
import { describe, it, before, after } from "node:test"
import { HyperBEAM } from "wao/test"
const seed = num => {
const array = new Array(num)
for (let i = 0; i < num; i++) array[i] = Math.floor(Math.random() * 256)
return Buffer.from(array).toString("base64")
}
const data = `
local count = 0
Handlers.add("Inc", "Inc", function (msg)
count = count + 1
msg.reply({ Data = "Count: "..tostring(count) })
end)
Handlers.add("Get", "Get", function (msg)
msg.reply({ Data = "Count: "..tostring(count) })
end)`
describe("Processes and Scheduler", function () {
let hbeam, hb
before(async () => {
hbeam = await new HyperBEAM({
reset: true,
as: ["genesis_wasm"]
}).ready()
hb = hbeam.hb
})
after(async () => hbeam.kill())
it("should spawn a legacynet AOS process", async () => {
const { process: pid } = await hb.p(
"/schedule",
{
device: "process@1.0",
type: "Process",
"data-protocol": "ao",
variant: "ao.TN.1",
scheduler: hb.addr,
"scheduler-location": hb.addr,
authority: hb.addr,
"random-seed": seed(16),
module: "ISShJH1ij-hPPt9St5UFFr_8Ys3Kj5cyg7zrMGt7H9s",
"scheduler-device": "scheduler@1.0",
"execution-device": "stack@1.0",
"device-stack": ["genesis-wasm@1.0", "patch@1.0"],
"push-device": "push@1.0",
"patch-from": "/results/outbox",
},
{ path: false }
)
await hb.p(
`/${pid}/schedule`,
{ type: "Message", target: pid, action: "Eval", data },
{ path: false }
)
await hb.p(
`/${pid}/schedule`,
{ type: "Message", target: pid, action: "Inc" },
{ path: false }
)
const { slot } = await hb.p(
`/${pid}/schedule`,
{ type: "Message", target: pid, action: "Inc" },
{ path: false }
)
const { results } = await hb.g(`/${pid}/compute`, { slot })
assert.equal("Count: 2", results.outbox["1"].data)
const { body } = await hb.post({
path: "/~relay@1.0/call",
method: "POST",
"relay-path": `http://localhost:6363/dry-run?process-id=${pid}`,
"content-type": "application/json",
"relay-body": JSON.stringify({
Tags: [{ name: "Action", value: "Get" }],
Owner: hb.addr,
}),
})
assert.equal(JSON.parse(body).Messages[0].Data, "Count: 2")
})
})
Dryruns
HyperBEAM introduces the patch@1.0
device and disables the traditional dryruns for performance reasons, but we can use the call
method on the relay@1.0
device to access the http://localhost:6363/dry-run
endpoint on the local CU server.
const { body } = await hb.post({
path: "/~relay@1.0/call",
method: "POST",
"relay-path": `http://localhost:6363/dry-run?process-id=${pid}`,
"content-type": "application/json",
"relay-body": JSON.stringify({
Tags: [{ name: "Action", value: "Get" }],
Owner: addr,
}),
})
assert.equal(JSON.parse(body).Messages[0].Data, "Count: 2")
WAO SDK
The HB
class has convenient methods for legacynet AOS. To write the same tests:
const { pid } = await hb.spawnLegacy()
await hb.scheduleLegacy({ pid, data })
const { slot } = await hb.scheduleLegacy({ pid, action: "Inc" })
const res = await hb.computeLegacy({ pid, slot })
assert.equal(res.Messages[0].Data, "Count: 1")
const { res: res2 } = await hb.messageLegacy({ pid, action: "Inc" })
assert.equal(res2.Messages[0].Data, "Count: 2")
const res3 = await hb.dryrun({ pid, action: "Get" })
assert.equal(res3.Messages[0].Data, "Count: 2")
The AO
class makes the code even more concise.
import { AO } from "wao"
const ao = await new AO({ module_type: "mainnet", hb: hbeam.url }).init(
hbeam.jwk
)
const { p } = await ao.deploy({ src_data: data })
await p.m("Inc")
assert.equal(await p.d("Get"), "Count: 1")
await p.m("Inc")
assert.equal(await p.d("Get"), "Count: 2")
Running Tests
You can find the working test file for this chapter here:
Run tests:
yarn test test/legacynet-aos.test.js
References
General
Device Docs
Device API
- dev_stack.erl
- dev_message.erl
- dev_process.erl
- dev_scheduler.erl
- dev_patch.erl
- dev_relay.erl
- dev_genesis_wasm.erl