git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit 1ae7957211ad80c5f9cafed6596df821709cdfe0

updated to use merkle tree

wanderer committed on 8/7/2017, 9:44:08 PM
Parent: b7561a6ca259ee9c581614ff1f8878ed5eeee970

Files changed

dfsChecker.jschanged
index.jschanged
package.jsonchanged
tests/index.jschanged
dfsChecker.jsView
@@ -6,9 +6,9 @@
66 * @param {object} state - the state containing all of the containers to search
77 * @param {string} root - the root id
88 * @param {Set} nodes - a set of nodes to start searching from
99 */
10-module.exports = async function DFSchecker (graph, state, root, nodes) {
10 +module.exports = async function DFSchecker (tree, root, nodes) {
1111 const checkedNodesSet = new Set()
1212 let hasRootSet = new Set()
1313 const promises = []
1414
@@ -58,9 +58,9 @@
5858 hasRootSet = checkedNodes
5959 return
6060 }
6161
62- const node = state[id]['/']
62 + const node = await tree.get(id)
6363 const promises = []
6464 // iterate through the nodes ports and recursivly check them
6565 for (const name in node.ports) {
6666 const port = node.ports[name]
index.jsView
@@ -1,20 +1,25 @@
1 +const Tree = require('merkle-radix-tree')
12 const Graph = require('ipld-graph-builder')
3 +const chunk = require('chunk')
24 const Message = require('primea-message')
35 const Kernel = require('./kernel.js')
46 const Scheduler = require('./scheduler.js')
57 const DFSchecker = require('./dfsChecker.js')
6-const chunk = require('chunk')
78
89 module.exports = class Hypervisor {
910 /**
1011 * The Hypervisor manages the container instances by instantiating them and
1112 * destorying them when possible. It also facilitates localating Containers
1213 * @param {Graph} dag an instance of [ipfs.dag](https://github.com/ipfs/interface-ipfs-core/tree/master/API/dag#dag-api)
1314 * @param {object} state - the starting state
1415 */
15- constructor (dag, state = {}) {
16 + constructor (dag, state = {'/': Tree.emptyTreeState}) {
1617 this.graph = new Graph(dag)
18 + this.tree = new Tree({
19 + graph: this.graph,
20 + root: state
21 + })
1722 this.scheduler = new Scheduler()
1823 this.state = state
1924 this._containerTypes = {}
2025 this._nodesToCheck = new Set()
@@ -35,13 +40,14 @@
3540 * given a port, this finds the corridsponeding endpoint port of the channel
3641 * @param {object} port
3742 * @returns {Promise}
3843 */
39- getDestPort (port) {
44 + async getDestPort (port) {
4045 if (port.destPort) {
4146 return port.destPort
4247 } else {
43- return this.graph.get(this.state, `${port.destId}/ports/${port.destName}`)
48 + const containerState = await this.tree.get(port.destId)
49 + return this.graph.get(containerState, `ports/${port.destName}`)
4450 }
4551 }
4652
4753 async send (port, message) {
@@ -56,9 +62,9 @@
5662 }
5763
5864 // loads an instance of a container from the state
5965 async _loadInstance (id) {
60- const state = await this.graph.get(this.state, id)
66 + const state = await this.tree.get(id)
6167 const container = this._containerTypes[state.type]
6268 let code
6369
6470 // checks if the code stored in the state is an array and that the elements
@@ -133,9 +139,9 @@
133139 state.code = message.data
134140 }
135141
136142 // save the container in the state
137- await this.graph.set(this.state, idHash, state)
143 + await this.tree.set(idHash, state)
138144 // create the container instance
139145 const instance = await this._loadInstance(idHash)
140146 resolve(instance)
141147 // send the intialization message
@@ -159,11 +165,11 @@
159165 * @returns {Promise}
160166 */
161167 async createStateRoot (ticks) {
162168 await this.scheduler.wait(ticks)
163- const unlinked = await DFSchecker(this.graph, this.state, this.ROOT_ID, this._nodesToCheck)
169 + const unlinked = await DFSchecker(this.tree, this.ROOT_ID, this._nodesToCheck)
164170 unlinked.forEach(id => {
165- delete this.state[id]
171 + this.tree.delete(id)
166172 })
167173 return this.graph.flush(this.state)
168174 }
169175
package.jsonView
@@ -33,8 +33,9 @@
3333 "binary-search-insert": "^1.0.3",
3434 "bn.js": "^4.11.6",
3535 "chunk": "0.0.2",
3636 "ipld-graph-builder": "1.2.5",
37 + "merkle-radix-tree": "0.0.4",
3738 "primea-message": "0.0.2"
3839 },
3940 "devDependencies": {
4041 "primea-abstract-container": "0.0.4",
tests/index.jsView
@@ -26,69 +26,82 @@
2626 tape('basic', async t => {
2727 t.plan(3)
2828 let message
2929 const expectedState = {
30- '/': 'zdpuAmN9VSrvNbArWkAEhEYaKhhCT3rk8xMhUam6eUfQmr6aZ'
30 + '/': 'zdpuAsvLUNKxnxpKxuipCJz7sH4kmHuu3gVEUEmJ1QuWnikht'
3131 }
3232
3333 class testVMContainer extends BaseContainer {
3434 onMessage (m) {
3535 t.true(m === message, 'should recive a message')
3636 }
3737 }
3838
39- const hypervisor = new Hypervisor(node.dag)
40- hypervisor.registerContainer(testVMContainer)
39 + try {
40 + const hypervisor = new Hypervisor(node.dag)
41 + hypervisor.registerContainer(testVMContainer)
4142
42- const rootContainer = await hypervisor.createInstance(testVMContainer.typeId)
43 + const rootContainer = await hypervisor.createInstance(testVMContainer.typeId)
4344
44- const [portRef1, portRef2] = rootContainer.ports.createChannel()
45- const initMessage = rootContainer.createMessage({
46- data: Buffer.from('test code'),
47- ports: [portRef2]
48- })
45 + const [portRef1, portRef2] = rootContainer.ports.createChannel()
46 + const initMessage = rootContainer.createMessage({
47 + data: Buffer.from('test code'),
48 + ports: [portRef2]
49 + })
4950
50- rootContainer.createInstance(testVMContainer.typeId, initMessage)
51 + rootContainer.createInstance(testVMContainer.typeId, initMessage)
5152
52- rootContainer.ports.bind('first', portRef1)
53- message = rootContainer.createMessage()
54- rootContainer.send(portRef1, message)
53 + rootContainer.ports.bind('first', portRef1)
54 + message = rootContainer.createMessage()
55 + rootContainer.send(portRef1, message)
5556
56- const stateRoot = await hypervisor.createStateRoot(Infinity)
57- t.deepEquals(stateRoot, expectedState, 'expected root!')
58- t.equals(hypervisor.scheduler.oldest(), 0)
57 + const stateRoot = await hypervisor.createStateRoot(Infinity)
58 + // await hypervisor.graph.tree(stateRoot, Infinity, true)
59 + // console.log(JSON.stringify(stateRoot, null, 2))
60 + t.deepEquals(stateRoot, expectedState, 'expected root!')
61 + t.equals(hypervisor.scheduler.oldest(), 0)
62 + } catch (e) {
63 + console.log(e)
64 + }
5965 })
6066
6167 tape('basic - do not store containers with no ports bound', async t => {
6268 t.plan(1)
6369 const expectedState = {
64- '/': 'zdpuAxGvPHM4DRbq7GeyGjwuPA8NT7DZLszcDDX9R5iwHWnTo'
70 + '/': 'zdpuAop4nt8pqzg7duciSYbZmWfDaBiz87RCtGCbb35ewUrbW'
6571 }
6672
6773 class testVMContainer extends BaseContainer {
6874 onCreation () {}
6975 }
7076
71- const hypervisor = new Hypervisor(node.dag)
72- hypervisor.registerContainer(testVMContainer)
77 + try {
78 + const hypervisor = new Hypervisor(node.dag)
79 + hypervisor.registerContainer(testVMContainer)
7380
74- const root = await hypervisor.createInstance(testVMContainer.typeId)
75- const [portRef1, portRef2] = root.ports.createChannel()
81 + const root = await hypervisor.createInstance(testVMContainer.typeId)
82 + const [portRef1, portRef2] = root.ports.createChannel()
7683
77- root.ports.bind('one', portRef1)
78- root.createInstance(testVMContainer.typeId, root.createMessage({
79- ports: [portRef2]
80- }))
84 + root.ports.bind('one', portRef1)
85 + root.createInstance(testVMContainer.typeId, root.createMessage({
86 + ports: [portRef2]
87 + }))
8188
82- const stateRoot = await hypervisor.createStateRoot(Infinity)
83- t.deepEquals(stateRoot, expectedState, 'expected root!')
89 + const stateRoot = await hypervisor.createStateRoot(Infinity)
90 +
91 + // await hypervisor.graph.tree(stateRoot, Infinity, true)
92 + // console.log(JSON.stringify(stateRoot, null, 2))
93 + t.deepEquals(stateRoot, expectedState, 'expected root!')
94 + } catch (e) {
95 + console.log(e)
96 + }
8497 })
8598
8699 tape('one child contract with saturated ports', async t => {
87100 t.plan(2)
88101 let message
89102 const expectedState = {
90- '/': 'zdpuAvWT2E1Hg6cvFNLTDbmjGRLSDbMnRtrA6s17oSdBX5EWs'
103 + '/': 'zdpuAnfZ1fGUSzNwAovfArzcTfEVbXjVYABprgtjUKMtGb8k5'
91104 }
92105
93106 class testVMContainer2 extends BaseContainer {
94107 onMessage (m) {
@@ -127,16 +140,19 @@
127140 })
128141
129142 root.send(portRef1, message)
130143 const stateRoot = await hypervisor.createStateRoot(Infinity)
144 +
145 + // await hypervisor.graph.tree(stateRoot, Infinity, true)
146 + // console.log(JSON.stringify(stateRoot, null, 2))
131147 t.deepEquals(stateRoot, expectedState, 'expected state')
132148 })
133149
134150 tape('one child contract', async t => {
135151 t.plan(4)
136152 let message
137153 const expectedState = {
138- '/': 'zdpuAvWT2E1Hg6cvFNLTDbmjGRLSDbMnRtrA6s17oSdBX5EWs'
154 + '/': 'zdpuArCqpDZtEqjrXrRhMiYLE7QQ1szVr1qLVkiwtDLincGWU'
139155 }
140156 let hasResolved = false
141157
142158 class testVMContainer2 extends BaseContainer {
@@ -184,8 +200,11 @@
184200
185201 root.send(portRef1, message)
186202 const stateRoot = await hypervisor.createStateRoot(Infinity)
187203 t.true(hasResolved, 'should resolve before generating the state root')
204 +
205 + // await hypervisor.graph.tree(stateRoot, Infinity, true)
206 + // console.log(JSON.stringify(stateRoot, null, 2))
188207 t.deepEquals(stateRoot, expectedState, 'expected state')
189208
190209 // test reviving the state
191210 class testVMContainer3 extends BaseContainer {
@@ -239,9 +258,9 @@
239258 await root.message(root.createMessage())
240259 const stateRoot = await hypervisor.createStateRoot()
241260
242261 t.deepEquals(stateRoot, {
243- '/': 'zdpuAwxK8kAM3SkxSyALurpFHTobp6sFJef9gZJ8ZDQRww1LN'
262 + '/': 'zdpuAtChoDT1Er7c9Ndv6ov4m46wibCNY1HKthoVLUn5n4Rg5'
244263 }, 'should revert the state')
245264 })
246265
247266 tape('message should arrive in the correct oder if sent in order', async t => {
@@ -845,9 +864,9 @@
845864 })
846865
847866 tape('port deletion', async t => {
848867 const expectedSr = {
849- '/': 'zdpuAqFMWKsATaU1gJwMTegcw18GFQ7szZix3QNgMN2sYm2vh'
868 + '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md'
850869 }
851870 class Root extends BaseContainer {
852871 onMessage (m) {
853872 const [portRef1, portRef2] = this.kernel.ports.createChannel()
@@ -888,15 +907,16 @@
888907 root.send(portRef1, message)
889908
890909 const sr = await hypervisor.createStateRoot()
891910 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
911 + await hypervisor.graph.tree(sr, Infinity, true)
892912
893913 t.end()
894914 })
895915
896916 tape('clear unbounded ports', async t => {
897917 const expectedSr = {
898- '/': 'zdpuAqFMWKsATaU1gJwMTegcw18GFQ7szZix3QNgMN2sYm2vh'
918 + '/': 'zdpuAxVzUQRWaAeFWXq5TgDpZqPaNgNp1ZuEfxbxg7h4qnXmC'
899919 }
900920 class Root extends BaseContainer {
901921 onMessage (m) {
902922 this.kernel.createInstance(Root.typeId)
@@ -923,9 +943,9 @@
923943 })
924944
925945 tape('should remove subgraphs', async t => {
926946 const expectedSr = {
927- '/': 'zdpuAqFMWKsATaU1gJwMTegcw18GFQ7szZix3QNgMN2sYm2vh'
947 + '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md'
928948 }
929949 class Root extends BaseContainer {
930950 onMessage (m) {
931951 const [, portRef2] = this.kernel.ports.createChannel()
@@ -969,9 +989,9 @@
969989 })
970990
971991 tape('should not remove connected nodes', async t => {
972992 const expectedSr = {
973- '/': 'zdpuAppPTaXwHnfU2yjtTyT9XsY7SJAkDwQWUZnkHU7myRzaj'
993 + '/': 'zdpuApKrsvsWknDML2Mme9FyZfRnVZ1hTCoKzkooYAWT3dUDV'
974994 }
975995 class Root extends BaseContainer {
976996 onMessage (m) {
977997 if (m.ports.length) {
@@ -1036,9 +1056,9 @@
10361056 })
10371057
10381058 tape('should remove multiple subgraphs', async t => {
10391059 const expectedSr = {
1040- '/': 'zdpuAvQqoEnojZHaw6dMDy8ACRVqfarfD2RCKTwFBYsj8suRC'
1060 + '/': 'zdpuAo1qZHhS6obxbGbtvnUxkbAxA6VSbcjYiiTVNWTm37xQv'
10411061 }
10421062 class Root extends BaseContainer {
10431063 onMessage (m) {
10441064 if (m.ports.length) {

Built with git-ssb-web