Commit af08dc3e0ce5be82ca5f4be87523656ed6ce5498
VM design according to the Monday call
Alex Beregszaszi committed on 8/23/2016, 12:27:46 AMParent: 553fa6781ed17dced2be7e810acef66344511e72
Files changed
index.js | changed |
index.js | ||
---|---|---|
@@ -31,9 +31,9 @@ | ||
31 | 31 | |
32 | 32 | // handles running code. |
33 | 33 | // NOTE: it assumes that wasm will raise an exception if something went wrong, |
34 | 34 | // otherwise execution succeeded |
35 | - static codeHandler (code, ethInterface = new Interface(new Environment())) { | |
35 | + codeHandler (code, ethInterface = new Interface(new Environment())) { | |
36 | 36 | const debugInterface = new DebugInterface(ethInterface.environment) |
37 | 37 | |
38 | 38 | const instance = Wasm.instantiateModule(code, { |
39 | 39 | 'ethereum': ethInterface.exportTable, |
@@ -60,21 +60,41 @@ | ||
60 | 60 | // loads code from the merkle trie and delegates the message |
61 | 61 | // Detects if code is EVM or WASM |
62 | 62 | // Detects if the code injection is needed |
63 | 63 | // Detects if transcompilation is needed |
64 | - callHandler (path, data) { | |
64 | + callHandler (address, gaslimit, gasprice, value, data) { | |
65 | + var toAccount = this.environment.accounts.get(new Uint8Array(address).toString()) | |
66 | + if (!toAccount) { | |
67 | + throw new Error('Account not found') | |
68 | + } | |
69 | + | |
65 | 70 | // creats a new Kernel |
66 | 71 | const environment = new Environment(data) |
67 | - // environment.parent = this | |
72 | + environment.parent = this | |
68 | 73 | const kernel = new Kernel(this, environment) |
69 | - const code = this.environment.state.get(path) | |
74 | + const code = this.environment.state.get(address) | |
75 | + | |
76 | + //environment.setCallHandler(callHandler) | |
77 | + | |
70 | 78 | if (!code) { |
71 | 79 | throw new Error('Contract not found') |
72 | 80 | } |
73 | 81 | if (!Utils.isWASMCode(code)) { |
74 | 82 | throw new Error('Not an eWASM contract') |
75 | 83 | } |
76 | 84 | kernel.codeHandler(code, new Interface(environment)) |
85 | + | |
86 | + // generate new stateroot | |
87 | + //this.environment.state.set(address, { stateRoot: stateRoot }) | |
88 | + | |
89 | + return { | |
90 | + executionOutcome: 1, // success | |
91 | + gasLeft: 0, | |
92 | + gasRefunds: 0, | |
93 | + returnValue: new ArrayBuffer(), | |
94 | + selfDestructAddress: new Uint8Array(), | |
95 | + logs: [] | |
96 | + } | |
77 | 97 | } |
78 | 98 | |
79 | 99 | // run tx; the tx message handler |
80 | 100 | runTx (tx, environment = new Environment()) { |
@@ -84,22 +104,48 @@ | ||
84 | 104 | // - ecrecover |
85 | 105 | // new ethTx(tx).validate(tx) |
86 | 106 | // - reduce balance |
87 | 107 | |
108 | + this.environment = environment | |
109 | + | |
88 | 110 | // Contract deployment |
89 | - const isDeployment = tx.data && !tx.to; | |
90 | - if (isDeployment) { | |
91 | - this.environment.accounts.set(new Uint8Array()) | |
111 | + //const isDeployment = tx.data && !tx.to; | |
112 | + //if (isDeployment) { | |
113 | + // this.environment.accounts.set(new Uint8Array()) | |
114 | + //} | |
115 | + | |
116 | + // | |
117 | + // environment.state - the merkle tree | |
118 | + // key: address (20 byte, hex string, without 0x prefix) | |
119 | + // every path has an account | |
120 | + // | |
121 | + // { balance, codeHash, stateRoot } | |
122 | + // | |
123 | + | |
124 | + // look up sender | |
125 | + let fromAccount = this.environment.accounts.get(new Uint8Array(tx.form).toString()) | |
126 | + | |
127 | + // deduct gasLimit * gasPrice from sender | |
128 | + if (fromAccount.balance < (tx.gasLimit * tx.gasPrice)) { | |
129 | + throw new Error('Insufficient account balance') | |
92 | 130 | } |
93 | 131 | |
94 | - var toAccount = this.environment.accounts.get(new Uint8Array(tx.to).toString()) | |
95 | - var fromAccount = this.environment.accounts.get(new Uint8Array(tx.form).toString()) | |
132 | + fromAccount.balance -= ts.gasLimit * tx.gasPrice | |
96 | 133 | |
97 | - if (!toAccount) { | |
98 | - throw new Error('Account not found') | |
134 | + let ret = this.callHandler(tx.to, tx.gasLimit, tx.gasPrice, tx.value, tx.data) | |
135 | + | |
136 | + // refund gas | |
137 | + if (ret.executionOutcome === 1) { | |
138 | + fromAccount.balance += (ret.gasLeft + ret.gasRefund) * tx.gasPrice | |
99 | 139 | } |
100 | 140 | |
101 | - this.callHandler(account.codeHash, environment) | |
141 | + // save new state? | |
142 | + | |
143 | + return { | |
144 | + returnValue: ret.returnValue, | |
145 | + gasLeft: ret.gasLeft, | |
146 | + logs: ret.logs | |
147 | + } | |
102 | 148 | } |
103 | 149 | |
104 | 150 | // run block; the block message handler |
105 | 151 | runBlock (block, environment = new Environment()) { |
Built with git-ssb-web