git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: e0d0380c051f78c76923c1d39111ee94896e3a8d

Files: e0d0380c051f78c76923c1d39111ee94896e3a8d / index.js

2448 bytesRaw
1const Graph = require('ipld-graph-builder')
2const multibase = require('multibase')
3const Kernel = require('./kernel.js')
4
5module.exports = class Hypervisor {
6 constructor (opts) {
7 this.graph = new Graph(opts.dag)
8 this._vmInstances = new Map()
9 this._VMs = {}
10 }
11
12 async getInstance (port, createIfNotFound = true) {
13 const id = await this.generateID(port)
14 let kernel = this._vmInstances.get(id)
15 if (!kernel && createIfNotFound) {
16 // load the the ID from the merkle store
17 await this.graph.tree(port.id, 1)
18 const parentID = await this.generateID({id: port.id['/'].parent})
19 const parentKernel = await this._vmInstances.get(parentID)
20 const parentPort = parentKernel.entryPort
21
22 kernel = await this.createInstanceFromPort(port, parentPort)
23 kernel.on('idle', () => {
24 this._vmInstances.delete(id)
25 })
26 }
27 return kernel
28 }
29
30 // given a port, wait untill its source contract has reached the threshold
31 // tick count
32 async wait (port, threshold, fromPort) {
33 let kernel = await this.getInstance(port, false)
34 if (kernel) {
35 return kernel.wait(threshold, fromPort)
36 } else {
37 return threshold
38 }
39 }
40
41 async createInstance (type, state, entryPort = null, parentPort) {
42 const VM = this._VMs[type]
43 if (!state) {
44 state = {
45 '/': VM.createState()
46 }
47 }
48
49 // create a new kernel instance
50 const kernel = new Kernel({
51 entryPort: entryPort,
52 parentPort: parentPort,
53 hypervisor: this,
54 state: state,
55 VM: VM
56 })
57
58 const id = await this.generateID(entryPort)
59 // save the newly created instance
60 this._vmInstances.set(id, kernel)
61 await kernel.start()
62 return kernel
63 }
64
65 /**
66 * opts.entryPort
67 * opts.parentPort
68 */
69 async createInstanceFromPort (entryPort, parentPort) {
70 const state = entryPort.link
71 return this.createInstance(entryPort.type, state, entryPort, parentPort)
72 }
73
74 async createStateRoot (container, ticks) {
75 await container.wait(ticks)
76 return this.graph.flush(container.state)
77 }
78
79 async generateID (port) {
80 if (!port || !port.id) {
81 return null
82 }
83
84 let id = Object.assign({}, port.id)
85 id = await this.graph.flush(id)
86 id = id['/']
87 if (Buffer.isBuffer(id)) {
88 id = multibase.encode('base58btc', id).toString()
89 }
90 return id
91 }
92
93 registerContainer (type, vm) {
94 this._VMs[type] = vm
95 }
96}
97

Built with git-ssb-web