vm.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. package ethvm
  2. import (
  3. "fmt"
  4. "math/big"
  5. "github.com/ethereum/eth-go/ethcrypto"
  6. "github.com/ethereum/eth-go/ethutil"
  7. )
  8. type Vm struct {
  9. env Environment
  10. err error
  11. depth int
  12. }
  13. func New(env Environment, typ Type) VirtualMachine {
  14. switch typ {
  15. case DebugVmTy:
  16. return NewDebugVm(env)
  17. default:
  18. return &Vm{env: env}
  19. }
  20. }
  21. func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
  22. self.depth++
  23. // Recover from any require exception
  24. defer func() {
  25. if r := recover(); r != nil {
  26. ret = closure.Return(nil)
  27. err = fmt.Errorf("%v", r)
  28. }
  29. }()
  30. // Don't bother with the execution if there's no code.
  31. if len(closure.Code) == 0 {
  32. return closure.Return(nil), nil
  33. }
  34. var (
  35. op OpCode
  36. mem = &Memory{}
  37. stack = NewStack()
  38. pc = 0
  39. step = 0
  40. require = func(m int) {
  41. if stack.Len() < m {
  42. panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
  43. }
  44. }
  45. )
  46. for {
  47. // The base for all big integer arithmetic
  48. base := new(big.Int)
  49. step++
  50. // Get the memory location of pc
  51. op := closure.GetOp(pc)
  52. gas := new(big.Int)
  53. addStepGasUsage := func(amount *big.Int) {
  54. gas.Add(gas, amount)
  55. }
  56. addStepGasUsage(GasStep)
  57. var newMemSize *big.Int = ethutil.Big0
  58. switch op {
  59. case STOP:
  60. gas.Set(ethutil.Big0)
  61. case SUICIDE:
  62. gas.Set(ethutil.Big0)
  63. case SLOAD:
  64. gas.Set(GasSLoad)
  65. case SSTORE:
  66. var mult *big.Int
  67. y, x := stack.Peekn()
  68. val := closure.GetStorage(x)
  69. if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
  70. mult = ethutil.Big2
  71. } else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
  72. mult = ethutil.Big0
  73. } else {
  74. mult = ethutil.Big1
  75. }
  76. gas = new(big.Int).Mul(mult, GasSStore)
  77. case BALANCE:
  78. gas.Set(GasBalance)
  79. case MSTORE:
  80. require(2)
  81. newMemSize = calcMemSize(stack.Peek(), u256(32))
  82. case MLOAD:
  83. require(1)
  84. newMemSize = calcMemSize(stack.Peek(), u256(32))
  85. case MSTORE8:
  86. require(2)
  87. newMemSize = calcMemSize(stack.Peek(), u256(1))
  88. case RETURN:
  89. require(2)
  90. newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
  91. case SHA3:
  92. require(2)
  93. gas.Set(GasSha)
  94. newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
  95. case CALLDATACOPY:
  96. require(2)
  97. newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
  98. case CODECOPY:
  99. require(3)
  100. newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
  101. case EXTCODECOPY:
  102. require(4)
  103. newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
  104. case CALL, CALLCODE:
  105. require(7)
  106. gas.Set(GasCall)
  107. addStepGasUsage(stack.data[stack.Len()-1])
  108. x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
  109. y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
  110. newMemSize = ethutil.BigMax(x, y)
  111. case CREATE:
  112. require(3)
  113. gas.Set(GasCreate)
  114. newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
  115. }
  116. if newMemSize.Cmp(ethutil.Big0) > 0 {
  117. newMemSize.Add(newMemSize, u256(31))
  118. newMemSize.Div(newMemSize, u256(32))
  119. newMemSize.Mul(newMemSize, u256(32))
  120. if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
  121. memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
  122. memGasUsage.Mul(GasMemory, memGasUsage)
  123. memGasUsage.Div(memGasUsage, u256(32))
  124. addStepGasUsage(memGasUsage)
  125. }
  126. }
  127. if !closure.UseGas(gas) {
  128. err := fmt.Errorf("Insufficient gas for %v. req %v has %v", op, gas, closure.Gas)
  129. closure.UseGas(closure.Gas)
  130. return closure.Return(nil), err
  131. }
  132. mem.Resize(newMemSize.Uint64())
  133. switch op {
  134. // 0x20 range
  135. case ADD:
  136. require(2)
  137. x, y := stack.Popn()
  138. base.Add(y, x)
  139. To256(base)
  140. // Pop result back on the stack
  141. stack.Push(base)
  142. case SUB:
  143. require(2)
  144. x, y := stack.Popn()
  145. base.Sub(y, x)
  146. To256(base)
  147. // Pop result back on the stack
  148. stack.Push(base)
  149. case MUL:
  150. require(2)
  151. x, y := stack.Popn()
  152. base.Mul(y, x)
  153. To256(base)
  154. // Pop result back on the stack
  155. stack.Push(base)
  156. case DIV:
  157. require(2)
  158. x, y := stack.Popn()
  159. if x.Cmp(ethutil.Big0) != 0 {
  160. base.Div(y, x)
  161. }
  162. To256(base)
  163. // Pop result back on the stack
  164. stack.Push(base)
  165. case SDIV:
  166. require(2)
  167. x, y := stack.Popn()
  168. if x.Cmp(ethutil.Big0) != 0 {
  169. base.Div(y, x)
  170. }
  171. To256(base)
  172. // Pop result back on the stack
  173. stack.Push(base)
  174. case MOD:
  175. require(2)
  176. x, y := stack.Popn()
  177. base.Mod(y, x)
  178. To256(base)
  179. stack.Push(base)
  180. case SMOD:
  181. require(2)
  182. x, y := stack.Popn()
  183. base.Mod(y, x)
  184. To256(base)
  185. stack.Push(base)
  186. case EXP:
  187. require(2)
  188. x, y := stack.Popn()
  189. base.Exp(y, x, Pow256)
  190. To256(base)
  191. stack.Push(base)
  192. case NEG:
  193. require(1)
  194. base.Sub(Pow256, stack.Pop())
  195. stack.Push(base)
  196. case LT:
  197. require(2)
  198. x, y := stack.Popn()
  199. // x < y
  200. if y.Cmp(x) < 0 {
  201. stack.Push(ethutil.BigTrue)
  202. } else {
  203. stack.Push(ethutil.BigFalse)
  204. }
  205. case GT:
  206. require(2)
  207. x, y := stack.Popn()
  208. // x > y
  209. if y.Cmp(x) > 0 {
  210. stack.Push(ethutil.BigTrue)
  211. } else {
  212. stack.Push(ethutil.BigFalse)
  213. }
  214. case SLT:
  215. require(2)
  216. x, y := stack.Popn()
  217. // x < y
  218. if y.Cmp(x) < 0 {
  219. stack.Push(ethutil.BigTrue)
  220. } else {
  221. stack.Push(ethutil.BigFalse)
  222. }
  223. case SGT:
  224. require(2)
  225. x, y := stack.Popn()
  226. // x > y
  227. if y.Cmp(x) > 0 {
  228. stack.Push(ethutil.BigTrue)
  229. } else {
  230. stack.Push(ethutil.BigFalse)
  231. }
  232. case EQ:
  233. require(2)
  234. x, y := stack.Popn()
  235. // x == y
  236. if x.Cmp(y) == 0 {
  237. stack.Push(ethutil.BigTrue)
  238. } else {
  239. stack.Push(ethutil.BigFalse)
  240. }
  241. case NOT:
  242. require(1)
  243. x := stack.Pop()
  244. if x.Cmp(ethutil.BigFalse) > 0 {
  245. stack.Push(ethutil.BigFalse)
  246. } else {
  247. stack.Push(ethutil.BigTrue)
  248. }
  249. // 0x10 range
  250. case AND:
  251. require(2)
  252. x, y := stack.Popn()
  253. stack.Push(base.And(y, x))
  254. case OR:
  255. require(2)
  256. x, y := stack.Popn()
  257. stack.Push(base.Or(y, x))
  258. case XOR:
  259. require(2)
  260. x, y := stack.Popn()
  261. stack.Push(base.Xor(y, x))
  262. case BYTE:
  263. require(2)
  264. val, th := stack.Popn()
  265. if th.Cmp(big.NewInt(32)) < 0 && th.Cmp(big.NewInt(int64(len(val.Bytes())))) < 0 {
  266. byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
  267. stack.Push(byt)
  268. } else {
  269. stack.Push(ethutil.BigFalse)
  270. }
  271. case ADDMOD:
  272. require(3)
  273. x := stack.Pop()
  274. y := stack.Pop()
  275. z := stack.Pop()
  276. base.Add(x, y)
  277. base.Mod(base, z)
  278. To256(base)
  279. stack.Push(base)
  280. case MULMOD:
  281. require(3)
  282. x := stack.Pop()
  283. y := stack.Pop()
  284. z := stack.Pop()
  285. base.Mul(x, y)
  286. base.Mod(base, z)
  287. To256(base)
  288. stack.Push(base)
  289. // 0x20 range
  290. case SHA3:
  291. require(2)
  292. size, offset := stack.Popn()
  293. data := ethcrypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
  294. stack.Push(ethutil.BigD(data))
  295. // 0x30 range
  296. case ADDRESS:
  297. stack.Push(ethutil.BigD(closure.Address()))
  298. case BALANCE:
  299. require(1)
  300. addr := stack.Pop().Bytes()
  301. balance := self.env.State().GetBalance(addr)
  302. stack.Push(balance)
  303. case ORIGIN:
  304. origin := self.env.Origin()
  305. stack.Push(ethutil.BigD(origin))
  306. case CALLER:
  307. caller := closure.caller.Address()
  308. stack.Push(ethutil.BigD(caller))
  309. case CALLVALUE:
  310. value := self.env.Value()
  311. stack.Push(value)
  312. case CALLDATALOAD:
  313. require(1)
  314. var (
  315. offset = stack.Pop()
  316. data = make([]byte, 32)
  317. lenData = big.NewInt(int64(len(closure.Args)))
  318. )
  319. if lenData.Cmp(offset) >= 0 {
  320. length := new(big.Int).Add(offset, ethutil.Big32)
  321. length = ethutil.BigMin(length, lenData)
  322. copy(data, closure.Args[offset.Int64():length.Int64()])
  323. }
  324. stack.Push(ethutil.BigD(data))
  325. case CALLDATASIZE:
  326. l := int64(len(closure.Args))
  327. stack.Push(big.NewInt(l))
  328. case CALLDATACOPY:
  329. var (
  330. size = int64(len(closure.Args))
  331. mOff = stack.Pop().Int64()
  332. cOff = stack.Pop().Int64()
  333. l = stack.Pop().Int64()
  334. )
  335. if cOff > size {
  336. cOff = 0
  337. l = 0
  338. } else if cOff+l > size {
  339. l = 0
  340. }
  341. code := closure.Args[cOff : cOff+l]
  342. mem.Set(mOff, l, code)
  343. case CODESIZE, EXTCODESIZE:
  344. var code []byte
  345. if op == EXTCODECOPY {
  346. addr := stack.Pop().Bytes()
  347. code = self.env.State().GetCode(addr)
  348. } else {
  349. code = closure.Code
  350. }
  351. l := big.NewInt(int64(len(code)))
  352. stack.Push(l)
  353. case CODECOPY, EXTCODECOPY:
  354. var code []byte
  355. if op == EXTCODECOPY {
  356. addr := stack.Pop().Bytes()
  357. code = self.env.State().GetCode(addr)
  358. } else {
  359. code = closure.Code
  360. }
  361. var (
  362. size = int64(len(code))
  363. mOff = stack.Pop().Int64()
  364. cOff = stack.Pop().Int64()
  365. l = stack.Pop().Int64()
  366. )
  367. if cOff > size {
  368. cOff = 0
  369. l = 0
  370. } else if cOff+l > size {
  371. l = 0
  372. }
  373. codeCopy := code[cOff : cOff+l]
  374. mem.Set(mOff, l, codeCopy)
  375. case GASPRICE:
  376. stack.Push(closure.Price)
  377. // 0x40 range
  378. case PREVHASH:
  379. prevHash := self.env.PrevHash()
  380. stack.Push(ethutil.BigD(prevHash))
  381. case COINBASE:
  382. coinbase := self.env.Coinbase()
  383. stack.Push(ethutil.BigD(coinbase))
  384. case TIMESTAMP:
  385. time := self.env.Time()
  386. stack.Push(big.NewInt(time))
  387. case NUMBER:
  388. number := self.env.BlockNumber()
  389. stack.Push(number)
  390. case DIFFICULTY:
  391. difficulty := self.env.Difficulty()
  392. stack.Push(difficulty)
  393. case GASLIMIT:
  394. // TODO
  395. stack.Push(big.NewInt(0))
  396. // 0x50 range
  397. case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
  398. a := int(op - PUSH1 + 1)
  399. val := ethutil.BigD(closure.GetBytes(int(pc+1), a))
  400. // Push value to stack
  401. stack.Push(val)
  402. pc += a
  403. step += int(op) - int(PUSH1) + 1
  404. case POP:
  405. require(1)
  406. stack.Pop()
  407. case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
  408. n := int(op - DUP1 + 1)
  409. stack.Dupn(n)
  410. case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
  411. n := int(op - SWAP1 + 2)
  412. stack.Swapn(n)
  413. case MLOAD:
  414. require(1)
  415. offset := stack.Pop()
  416. val := ethutil.BigD(mem.Get(offset.Int64(), 32))
  417. stack.Push(val)
  418. case MSTORE: // Store the value at stack top-1 in to memory at location stack top
  419. require(2)
  420. // Pop value of the stack
  421. val, mStart := stack.Popn()
  422. mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
  423. case MSTORE8:
  424. require(2)
  425. off := stack.Pop()
  426. val := stack.Pop()
  427. mem.store[off.Int64()] = byte(val.Int64() & 0xff)
  428. case SLOAD:
  429. require(1)
  430. loc := stack.Pop()
  431. val := closure.GetStorage(loc)
  432. stack.Push(val.BigInt())
  433. case SSTORE:
  434. require(2)
  435. val, loc := stack.Popn()
  436. closure.SetStorage(loc, ethutil.NewValue(val))
  437. closure.message.AddStorageChange(loc.Bytes())
  438. case JUMP:
  439. require(1)
  440. pc = int(stack.Pop().Int64())
  441. // Reduce pc by one because of the increment that's at the end of this for loop
  442. continue
  443. case JUMPI:
  444. require(2)
  445. cond, pos := stack.Popn()
  446. if cond.Cmp(ethutil.BigTrue) >= 0 {
  447. pc = int(pos.Int64())
  448. if closure.GetOp(int(pc)) != JUMPDEST {
  449. return closure.Return(nil), fmt.Errorf("JUMP missed JUMPDEST %v", pc)
  450. }
  451. continue
  452. }
  453. case JUMPDEST:
  454. case PC:
  455. stack.Push(u256(int64(pc)))
  456. case MSIZE:
  457. stack.Push(big.NewInt(int64(mem.Len())))
  458. case GAS:
  459. stack.Push(closure.Gas)
  460. // 0x60 range
  461. case CREATE:
  462. require(3)
  463. var (
  464. err error
  465. value = stack.Pop()
  466. size, offset = stack.Popn()
  467. input = mem.Get(offset.Int64(), size.Int64())
  468. gas = new(big.Int).Set(closure.Gas)
  469. // Snapshot the current stack so we are able to
  470. // revert back to it later.
  471. //snapshot = self.env.State().Copy()
  472. )
  473. // Generate a new address
  474. addr := ethcrypto.CreateAddress(closure.Address(), closure.object.Nonce)
  475. closure.object.Nonce++
  476. closure.UseGas(closure.Gas)
  477. msg := NewExecution(self, addr, input, gas, closure.Price, value)
  478. ret, err := msg.Exec(addr, closure)
  479. if err != nil {
  480. stack.Push(ethutil.BigFalse)
  481. // Revert the state as it was before.
  482. //self.env.State().Set(snapshot)
  483. } else {
  484. msg.object.Code = ret
  485. stack.Push(ethutil.BigD(addr))
  486. }
  487. case CALL, CALLCODE:
  488. require(7)
  489. gas := stack.Pop()
  490. // Pop gas and value of the stack.
  491. value, addr := stack.Popn()
  492. // Pop input size and offset
  493. inSize, inOffset := stack.Popn()
  494. // Pop return size and offset
  495. retSize, retOffset := stack.Popn()
  496. // Get the arguments from the memory
  497. args := mem.Get(inOffset.Int64(), inSize.Int64())
  498. //snapshot := self.env.State().Copy()
  499. var executeAddr []byte
  500. if op == CALLCODE {
  501. executeAddr = closure.Address()
  502. } else {
  503. executeAddr = addr.Bytes()
  504. }
  505. msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
  506. ret, err := msg.Exec(addr.Bytes(), closure)
  507. if err != nil {
  508. stack.Push(ethutil.BigFalse)
  509. //self.env.State().Set(snapshot)
  510. } else {
  511. stack.Push(ethutil.BigTrue)
  512. mem.Set(retOffset.Int64(), retSize.Int64(), ret)
  513. }
  514. case RETURN:
  515. require(2)
  516. size, offset := stack.Popn()
  517. ret := mem.Get(offset.Int64(), size.Int64())
  518. return closure.Return(ret), nil
  519. case SUICIDE:
  520. require(1)
  521. receiver := self.env.State().GetOrNewStateObject(stack.Pop().Bytes())
  522. receiver.AddAmount(closure.object.Balance)
  523. closure.object.MarkForDeletion()
  524. fallthrough
  525. case STOP: // Stop the closure
  526. return closure.Return(nil), nil
  527. default:
  528. vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
  529. //panic(fmt.Sprintf("Invalid opcode %x", op))
  530. return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
  531. }
  532. pc++
  533. }
  534. }
  535. func (self *Vm) Env() Environment {
  536. return self.env
  537. }
  538. func (self *Vm) Depth() int {
  539. return self.depth
  540. }