Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache API #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions assembly/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export declare function load(ptr: u32, offset: u32, len: u32): void;
export declare function save(ptr: u32, offset: u32, len: u32): void;
9 changes: 7 additions & 2 deletions assembly/hello-world/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as env from '../env'
import * as bignum from '../bignum'
import * as cache from '../cache'

/*
* Increments preStateRoot by one
* Increments preStateRoot by the cached value of previous block data
*/
export function main(): void {
var preStateRootPtr: u32 = __heap_base
Expand All @@ -11,9 +12,13 @@ export function main(): void {
var postStateRootPtr: u32 = __heap_base + 32

var numPtr: u32 = __heap_base + 64
store<u8>(numPtr, 1, 31)
cache.load(numPtr, 0, 32)

bignum.add256(preStateRootPtr, numPtr, postStateRootPtr)

var blockDataPtr: u32 = __heap_base + 96
env.eth2_blockDataCopy(blockDataPtr, 0, 32)
cache.save(blockDataPtr, 0, 32)

env.eth2_savePostStateRoot(postStateRootPtr)
}
9 changes: 7 additions & 2 deletions src/browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { safeLoad } = require('js-yaml')
const { TestCase, parseYaml, getImports, setMemory, getRes } = require('../dist/lib')
const { TestCase, parseYaml, getImports, setMemory, getRes, CACHE_SIZE } = require('../dist/lib')

async function main() {
let yamlPath = 'test.yaml'
Expand All @@ -10,12 +10,17 @@ async function main() {
const wasmResponse = await fetch(testCase.script)
const wasmBuffer = await wasmResponse.arrayBuffer()
let preStateRoot = testCase.preStateRoot
let readableCache = Buffer.alloc(CACHE_SIZE)
let writableCache = Buffer.alloc(CACHE_SIZE)
for (const block of testCase.blocks) {
const compiled = await WebAssembly.instantiate(wasmBuffer, getImports({ preStateRoot, blockData: block }))
const compiled = await WebAssembly.instantiate(wasmBuffer, getImports({ preStateRoot, blockData: block, readableCache, writableCache }))
const instance = compiled.instance
setMemory(instance.exports.memory)
instance.exports.main()
preStateRoot = getRes()

readableCache = writableCache
writableCache = Buffer.alloc(CACHE_SIZE)
}
if (!testCase.postStateRoot.equals(getRes())) {
console.error('Assertion failed, post state root doesn\'t match')
Expand Down
11 changes: 9 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as assert from 'assert'
import * as fs from 'fs'
import { safeLoad } from 'js-yaml'
import { TestCase, parseYaml, getImports, setMemory, getRes } from './lib'
import { TestCase, parseYaml, getImports, setMemory, getRes, CACHE_SIZE } from './lib'

function main() {
let yamlPath
Expand All @@ -19,14 +19,21 @@ function main() {
const wasmFile = fs.readFileSync(testCase.script)
const wasmModule = new WebAssembly.Module(wasmFile)
let preStateRoot = testCase.preStateRoot
let readableCache = Buffer.alloc(CACHE_SIZE)
let writableCache = Buffer.alloc(CACHE_SIZE)
for (const block of testCase.blocks) {
const instance = new WebAssembly.Instance(wasmModule, getImports({ preStateRoot, blockData: block }))
const instance = new WebAssembly.Instance(wasmModule, getImports({ preStateRoot, blockData: block, readableCache, writableCache }))
setMemory(instance.exports.memory)

let t = process.hrtime()
instance.exports.main()
t = process.hrtime(t)
console.log('benchmark took %d seconds and %d nanoseconds (%d ms)', t[0], t[1], t[1] / 1000000)

preStateRoot = getRes()

readableCache = writableCache
writableCache = Buffer.alloc(CACHE_SIZE)
}
assert(testCase.postStateRoot.equals(getRes()), `expected ${testCase.postStateRoot.toString('hex')}, received ${getRes().toString('hex')}`)
}
Expand Down
15 changes: 15 additions & 0 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { safeLoad } from 'js-yaml'
import BN = require('bn.js')
import { TWO_POW256 } from 'ethereumjs-util'

// Cache size in bytes
export const CACHE_SIZE = 256 * 1024

let mem: WebAssembly.Memory
let res: Buffer

Expand Down Expand Up @@ -37,6 +40,8 @@ export interface TestCase {
export interface EnvData {
preStateRoot: Buffer
blockData: Buffer
readableCache: Buffer
writableCache: Buffer
}

export const getImports = (env: EnvData) => {
Expand All @@ -58,6 +63,16 @@ export const getImports = (env: EnvData) => {
debug_endTimer: () => console.log('end timer'),
abort: () => { throw ('Wasm aborted') }
},
cache: {
load: (ptr: number, offset: number, len: number) => {
const c = env.readableCache.slice(offset, offset + len)
memset(mem, ptr, c)
},
save: (ptr: number, offset: number, len: number) => {
const c = memget(mem, ptr, len)
env.writableCache.write(c.toString('hex'), offset, len, 'hex')
}
},
bignum: {
add256: (aOffset: number, bOffset: number, cOffset: number) => {
const a = new BN(memget(mem, aOffset, 32))
Expand Down
8 changes: 5 additions & 3 deletions test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ shard_pre_state:
- "0000000000000000000000000000000000000000000000000000000000000001"
shard_blocks:
- env: 0
data: ""
data: "0000000000000000000000000000000000000000000000000000000000000005"
- env: 0
data: ""
data: "0000000000000000000000000000000000000000000000000000000000000007"
- env: 0
data: "000000000000000000000000000000000000000000000000000000000000000b"
shard_post_state:
exec_env_states:
- "0000000000000000000000000000000000000000000000000000000000000003"
- "000000000000000000000000000000000000000000000000000000000000000d"