Skip to content
This repository was archived by the owner on May 2, 2022. It is now read-only.
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
39 changes: 25 additions & 14 deletions dmap.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const ebnf = require('ebnf')
const multiformats = require('multiformats')
const prefLenIndex = 2
const fail =s=> { throw new Error(s) }
const need =(b,s)=> b || fail(s)
const fail = s => {
throw new Error(s)
}
const need = (b, s) => b || fail(s)

module.exports = lib = {}

Expand All @@ -14,16 +16,25 @@ name ::= [a-z0-9]+
rune ::= ":" | "."
`
lib.parser = new ebnf.Parser(ebnf.Grammars.W3C.getRules(lib.grammar))
lib.parse =s=> {
lib.parse = s => {
const ast = lib.parser.getAST(s)
const flat = lib.postparse(ast)
return flat[0]
}
lib.postparse =ast=> [ast.children.map(step => ({locked: step.children.find(({ type }) => type === 'rune').text === ":",
name: step.children.find(({ type }) => type === 'name').text}))]

lib.postparse = (ast) => {
const locked = step => step.children.find(({type}) => type === 'rune').text === ":"
const name = step => step.children.find(({type}) => type === 'name').text
const parsed = ast.children.map(
step => ({
locked: locked(step),
name: name(step)
}))
return [parsed]
}

lib._walk = async (dmap, path, register, reg_meta, ctx, trace) => {
trace.push({ path, register, reg_meta, ctx })
trace.push({path, register, reg_meta, ctx})
if (path.length == 0) {
return trace
}
Expand All @@ -32,33 +43,33 @@ lib._walk = async (dmap, path, register, reg_meta, ctx, trace) => {
}

const step = path[0]
rest = path.slice(1)
const rest = path.slice(1)
const addr = register.slice(0, 21 * 2)
const fullname = '0x' + Buffer.from(step.name).toString('hex') + '00'.repeat(32-step.name.length)
const fullname = '0x' + Buffer.from(step.name).toString('hex') + '00'.repeat(32 - step.name.length)
const [meta, data] = await dmap.get(addr, fullname)
if (step.locked) {
need(ctx.locked, `Encountered ':' in unlocked subpath`)
need((Buffer.from(meta.slice(2), 'hex')[0] & lib.FLAG_LOCK) !== 0, `Entry is not locked`)
return await lib._walk(dmap, rest, data, meta, {locked:true}, trace)
return lib._walk(dmap, rest, data, meta, {locked: true}, trace)
} else {
return await lib._walk(dmap, rest, data, meta, {locked:false}, trace)
return lib._walk(dmap, rest, data, meta, {locked: false}, trace)
}
}

lib._slot = async (dmap, key) => {
need(dmap.provider, `walk: no provider on given dmap object`)
return await dmap.provider.getStorageAt(dmap.address, key)
return dmap.provider.getStorageAt(dmap.address, key)
}

lib.walk = async (dmap, path) => {
if ( path.length > 0 && ![':', '.'].includes(path.charAt(0))) {
path = ':' + path
}
const root = await lib._slot(dmap, '0x' + '00'.repeat(32))
const meta = await lib._slot(dmap, '0x' + '00'.repeat(31) + '01')
const meta = await lib._slot(dmap, '0x' + '00'.repeat(32))
const root = await lib._slot(dmap, '0x' + '00'.repeat(31) + '01')
const steps = lib.parse(path)
const trace = await lib._walk(dmap, steps, root, meta, {locked: path.charAt(0) === ':'}, [])
return {'meta': trace[trace.length-1].reg_meta, 'data': trace[trace.length-1].register}
return {'meta': trace[trace.length - 1].reg_meta, 'data': trace[trace.length - 1].register}
}

lib.prepareCID = (cidStr, lock) => {
Expand Down
14 changes: 7 additions & 7 deletions sol/dmap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ contract Dmap {

constructor(address rootzone) {
assembly {
sstore(0, shl(96, rootzone))
sstore(1, FLAG_LOCK)
sstore(1, shl(96, rootzone))
sstore(0, FLAG_LOCK)
}
}

Expand All @@ -23,8 +23,8 @@ contract Dmap {
mstore(0, zone)
mstore(32, name)
let slot := keccak256(0, 64)
mstore(0, sload(add(slot, 1)))
mstore(32, sload(slot))
mstore(32, sload(add(slot, 1)))
mstore(0, sload(slot))
return(0, 64)
}
}
Expand All @@ -36,9 +36,9 @@ contract Dmap {
mstore(0, caller())
let slot0 := keccak256(0, 64)
let slot1 := add(slot0, 1)
if iszero(and(FLAG_LOCK, sload(slot1))) {
sstore(slot0, data)
sstore(slot1, meta)
if iszero(and(FLAG_LOCK, sload(slot0))) {
sstore(slot1, data)
sstore(slot0, meta)
return(0, 0)
}
mstore(0, SIG_LOCK)
Expand Down
4 changes: 2 additions & 2 deletions test/dmap-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ describe('dmap', ()=>{
await check_entry(BOB, b32('1'), constants.HashZero, constants.HashZero)

// dmap.get returns (meta, data), internal storage is (data, meta)
const rootData = await dmap.provider.getStorageAt(dmap.address, 0)
const rootMeta = await dmap.provider.getStorageAt(dmap.address, 1)
const rootData = await dmap.provider.getStorageAt(dmap.address, 1)
const rootMeta = await dmap.provider.getStorageAt(dmap.address, 0)
want(ethers.utils.hexDataSlice(rootData, 0, 20))
.to.eql(rootzone.address.toLowerCase())
want(rootMeta).to.eql(LOCK)
Expand Down