git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 81bc698eafe0e2013602fe8f6e9aae6fe7b0ee7b

Files: 81bc698eafe0e2013602fe8f6e9aae6fe7b0ee7b / interface.js

11752 bytesRaw
1/**
2 * This is the Ethereum interface that is exposed to the WASM instance which
3 * enables to interact with the Ethereum Environment
4 */
5const Environment = require('./environment.js')
6const constants = require('./constants.js')
7
8// function.bind is not working corretly whith Wasm imports. So instead create
9// a global for now. TODO REMOVE
10let ENV
11let MOD
12// The interface exposed to the WebAessembly Core
13module.exports = class Interface {
14
15 debugPrint (a) {
16 console.log(a)
17 }
18
19 memPrint () {
20 console.log((new Uint8Array(MOD.exports.memory)).toString())
21 }
22
23 constructor (environment = new Environment()) {
24 ENV = this.environment = environment
25 }
26
27 setModule (mod) {
28 this.module = MOD = mod
29 }
30
31 /**
32 * Subtracts an amount to the gas counter
33 * @param {integer} amount the amount to subtract to the gas counter
34 */
35 addGas (amount) {
36 if (amount > 0) {
37 ENV.gasCounter += amount
38 }
39 }
40
41 /**
42 * Returns the current gasCounter
43 * @return {integer}
44 */
45 gasUsed () {
46 return ENV.gasCounter
47 }
48
49 /**
50 * Returns the current gasCounter
51 * @return {integer}
52 */
53 gasLeft () {
54 return ENV.gas - ENV.gasCounter
55 }
56
57 /**
58 * Gets address of currently executing account and loads it into memory at
59 * the given offset.
60 * @param {integer} offset
61 */
62 address (offset) {
63 const address = ENV.address
64 const memory = new Uint8Array(MOD.exports.memory, offset, constants.ADD_SIZE_BYTES)
65 memory.set(address)
66 }
67
68 /**
69 * Gets balance of the given account and loads it into memory at the given
70 * offset.
71 * @param {integer} addressOffset the memory offset to laod the address
72 * @param {integer} resultOffset
73 */
74 balance (addressOffset, offset) {
75 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
76 const memory = new Uint8Array(MOD.exports.memory, offset, constants.MAX_BAL_BYTES)
77 const balance = ENV.getBalance(address)
78 memory.set(balance)
79 }
80
81 /**
82 * Gets the execution's origination address and loads it into memory at the
83 * given offset. This is the sender of original transaction; it is never an
84 * account with non-empty associated code.
85 * @param {integer} offset
86 */
87 origin (offset) {
88 const origin = ENV.origin
89 const memory = new Uint8Array(MOD.exports.memory, offset, constants.ADD_SIZE_BYTES)
90 memory.set(origin)
91 }
92
93 /**
94 * Gets caller address and loads it into memory at the given offset. This is
95 * the address of the account that is directly responsible for this execution.
96 * @param {integer} offset
97 */
98 caller (offset) {
99 const caller = ENV.caller
100 const memory = new Uint8Array(MOD.exports.memory, offset, constants.ADD_SIZE_BYTES)
101 memory.set(caller)
102 }
103
104 /**
105 * Gets the deposited value by the instruction/transaction responsible for
106 * this execution and loads it into memory at the given location.
107 * @param {integer} offset
108 */
109 callValue (offset) {
110 const callValue = ENV.callValue
111 const memory = new Uint8Array(MOD.exports.memory, offset, constants.MAX_BAL_BYTES)
112 memory.set(callValue)
113 }
114
115 /**
116 * Get size of input data in current environment. This pertains to the input
117 * data passed with the message call instruction or transaction.
118 * @return {integer}
119 */
120 callDataSize () {
121 return ENV.callData.byteLength
122 }
123
124 /**
125 * Copys the input data in current environment to memory. This pertains to
126 * the input data passed with the message call instruction or transaction.
127 * @param {integer} offset the offset in memory to load into
128 * @param {integer} dataOffset the offset in the input data
129 * @param {integer} length the length of data to copy
130 */
131 callDataCopy (offset, dataOffset, length) {
132 const callData = new Uint8Array(ENV.callData, offset, length)
133 const memory = new Uint8Array(MOD.exports.memory, offset, length)
134 memory.set(callData)
135 }
136
137 /**
138 * Gets the size of code running in current environment.
139 * @return {interger}
140 */
141 codeSize () {
142 return ENV.code.byteLength
143 }
144
145 /**
146 * Copys the code running in current environment to memory.
147 * @param {integer} offset the memory offset
148 * @param {integer} codeOffset the code offset
149 * @param {integer} length the length of code to copy
150 */
151 codeCopy (offset, codeOffset, length) {
152 const code = new Uint8Array(ENV.code, codeOffset, length)
153 const memory = new Uint8Array(MOD.exports.memory, offset, length)
154 memory.set(code)
155 }
156
157 /**
158 * Get size of an account’s code.
159 * @param {integer} addressOffset the offset in memory to load the address from
160 * @return {integer}
161 */
162 extCodeSize (addressOffset) {
163 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
164 const code = this.environment.getCode(address)
165 return code.byteLength
166 }
167
168 /**
169 * Copys the code of an account to memory.
170 * @param {integer} addressOffset the memory offset of the address
171 * @param {integer} offset the memory offset
172 * @param {integer} codeOffset the code offset
173 * @param {integer} length the length of code to copy
174 */
175 extCodeCopy (addressOffset, offset, codeOffset, length) {
176 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
177 let code = this.environment.getCode(address)
178 code = new Uint8Array(code, codeOffset, length)
179 const memory = new Uint8Array(MOD.exports.memory, offset, length)
180 memory.set(code)
181 }
182
183 /**
184 * Gets price of gas in current environment.
185 * @return {integer}
186 */
187 gasPrice () {
188 return ENV.gasPrice
189 }
190
191 /**
192 * Gets the hash of one of the 256 most recent complete blocks.
193 * @param {integer} number which block to load
194 * @param {integer} offset the offset to load the hash into
195 */
196 blockHash (number, offset) {
197 const hash = this.environment.getBlockHash(number)
198 const memory = new Uint8Array(MOD.exports.memory, offset, constants.ADD_SIZE_BYTES)
199 memory.set(hash)
200 }
201
202 /**
203 * Gets the block’s beneficiary address and loads into memory.
204 * @param offset
205 */
206 coinbase (offset) {
207 const memory = new Uint8Array(MOD.exports.memory, offset, constants.ADD_SIZE_BYTES)
208 memory.set(ENV.coinbase)
209 }
210
211 /**
212 * Get the block’s timestamp.
213 * @return {integer}
214 */
215 timestamp () {
216 return ENV.timestamp
217 }
218
219 /**
220 * Get the block’s number.
221 * @return {integer}
222 */
223 number () {
224 return ENV.number
225 }
226
227 /**
228 * Get the block’s difficulty.
229 * @return {integer}
230 */
231 difficulty () {
232 return ENV.difficulty
233 }
234
235 /**
236 * Get the block’s gas limit.
237 * @return {integer}
238 */
239 gasLimit () {
240 return ENV.gasLimit
241 }
242
243 /**
244 * Creates a new log in the current environment
245 * @param {integer} dataOffset the offset in memory to load the memory
246 * @param {integer} length the data length
247 * TODO: replace with variadic
248 */
249 log (dataOffset, length, topic1, topic2, topic3, topic4, topic5) {
250 const data = new Uint8Array(MOD.exports.memory, dataOffset, length)
251 ENV.logs.push({
252 data: data,
253 topics: [topic1, topic2, topic3, topic4, topic5]
254 })
255 }
256
257 /**
258 * Creates a new contract with a given value.
259 * @param {integer} valueOffset the offset in memory to the value from
260 * @param {integer} dataOffset the offset to load the code for the new contract from
261 * @param {integer} length the data length
262 */
263 create (valueOffset, dataOffset, length) {
264 const value = new Uint8Array(MOD.exports.memory, valueOffset, constants.MAX_BAL_BYTES)
265 const data = new Uint8Array(MOD.exports.memory, dataOffset, length)
266 const result = ENV.create(value, data)
267 return result
268 }
269
270 /**
271 * Sends a message with arbiatary data to a given address path
272 * @param {integer} addressOffset the offset to load the address path from
273 * @param {integer} valueOffset the offset to load the value from
274 * @param {integer} dataOffset the offset to load data from
275 * @param {integer} dataLength the length of data
276 * @param {integer} resultOffset the offset to store the result data at
277 * @param {integer} resultLength
278 * @param {integer} gas
279 * @return {integer} Returns 1 or 0 depending on if the VM trapped on the message or not
280 * TODO: add proper gas counting
281 */
282 call (addressOffset, valueOffset, dataOffset, dataLength, resultOffset, resultLength, gas) {
283 if (gas === undefined) {
284 gas = this.gasLeft()
285 }
286 // Load the params from mem
287 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
288 const value = new Uint8Array(MOD.exports.memory, valueOffset, constants.MAX_BAL_BYTES)
289 const data = new Uint8Array(MOD.exports.memory, dataOffset, dataLength)
290 // Run the call
291 const [result, errorCode] = ENV.call(gas, address, value, data)
292 const memory = new Uint8Array(MOD.exports.memory, resultOffset, resultLength)
293 memory.set(result)
294
295 return errorCode
296 }
297
298 /**
299 * Message-call into this account with an alternative account’s code, but
300 * persisting the current values for sender and value.
301 * @param {integer} gas
302 * @param {integer} addressOffset the offset to load the address path from
303 * @param {integer} valueOffset the offset to load the value from
304 * @param {integer} dataOffset the offset to load data from
305 * @param {integer} dataLength the length of data
306 * @param {integer} resultOffset the offset to store the result data at
307 * @param {integer} resultLength
308 * @return {integer} Returns 1 or 0 depending on if the VM trapped on the message or not
309 */
310 callDelegate (gas, addressOffset, dataOffset, dataLength, resultOffset, resultLength) {
311 const data = new Uint8Array(MOD.exports.memory, dataOffset, dataLength)
312 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
313 const [result, errorCode] = this.environment.callDelegate(gas, address, data)
314 const memory = new Uint8Array(MOD.exports.memory, resultOffset, resultLength)
315 memory.set(result)
316
317 return errorCode
318 }
319
320 /**
321 * store a value at a given path in long term storage which are both loaded
322 * from Memory
323 * @param {interger} pathOffest the memory offset to load the the path from
324 * @param {interger} valueOffset the memory offset to load the value from
325 */
326 sstore (pathOffest, valueOffset) {
327 const path = new Uint8Array(MOD.exports.memory, pathOffest, pathOffest + 32)
328 const value = new Uint8Array(MOD.exports.memory, valueOffset, valueOffset + 32)
329 ENV.state.set(path, value)
330 }
331
332 /**
333 * reterives a value at a given path in long term storage
334 * @param {interger} pathOffest the memory offset to load the the path from
335 * @param {interger} resultOffset the memory offset to load the value from
336 */
337 sload (pathOffest, resultOffset) {
338 const path = new Uint8Array(MOD.exports.memory, pathOffest, pathOffest + 32)
339 const result = ENV.state.getValue(path)
340 const memory = new Uint8Array(MOD.exports.memory, resultOffset, resultOffset + 32)
341 memory.set(result)
342 }
343
344 /**
345 * Halt execution returning output data.
346 * @param {integer} offset the offset of the output data.
347 * @param {integer} length the length of the output data.
348 */
349 return (offset, length) {
350 this.environment.returnValue = new Uint8Array(MOD.exports.memory, offset, length)
351 }
352
353 /**
354 * Halt execution and register account for later deletion giving the remaining
355 * balance to an address path
356 * @param {integer} offset the offset to load the address from
357 */
358 suicide (addressOffset) {
359 const address = new Uint8Array(MOD.exports.memory, addressOffset, constants.ADD_SIZE_BYTES)
360 this.environment.suicideAddress = address
361 }
362}
363

Built with git-ssb-web