forked from cerc-io/plugeth
78fb2af6f1
commit79d7cbfc4a
Merge:9120274
1c1ba8d
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Nov 4 13:32:11 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit9120274a46
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Nov 4 13:31:27 2014 +0100 Update tests to latest protocol changes (PoC7) commit1c1ba8d161
Merge:014d370
3aebe53
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Nov 4 13:30:52 2014 +0100 Merge pull request #31 from CJentzsch/develop Restructered tests in folders in accordance to test suites commit3aebe532e5
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Nov 3 13:58:21 2014 +0100 Updated vmNamecoin.json to new sstore prices commit8a0be21839
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Nov 3 13:53:00 2014 +0100 Added example state test commit83643addbc
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Nov 3 13:36:25 2014 +0100 removed systemoperationstests commit3930ca3a9a
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Nov 3 13:22:15 2014 +0100 Restructered tests in folders in accordance to test suites commit014d370b5d
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 29 21:23:56 2014 +0100 New SIGNEXTEND tets commit155d449be2
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 29 20:59:05 2014 +0100 New tests for BNOT and SIGNEXTEND commitc9eae764b8
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 28 12:58:27 2014 +0100 Update SSTORE gas cost and BNOT instead of NEG commitad2a75ac58
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Thu Oct 23 16:05:49 2014 +0200 Added new recursive bombs commit834c52af64
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Thu Oct 23 12:01:05 2014 +0200 Changing gas cost to zero at stackunderflow commitc73a8a89d2
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Wed Oct 22 13:04:45 2014 +0200 Reverted back to original value. commitb9a8c92422
Author: martin becze <wanderer@users.noreply.github.com> Date: Tue Oct 21 17:02:52 2014 -0400 fix spelling error commitb48ae74af4
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 21 17:26:26 2014 +0200 Added failing random tests commitbee0a4100c
Merge:5050d20
b315da6
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 21 17:15:05 2014 +0200 Merge remote-tracking branch 'origin/master' into develop commit5050d20b4d
Merge:7516685
ba35362
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Oct 20 20:18:20 2014 +0200 Merge pull request #26 from wanderer/develop Add a package.json for node.js commitba35362876
Author: wanderer <mjbecze@gmail.com> Date: Sun Oct 19 23:59:47 2014 -0400 turned tests into a node module commit751668571e
Author: ethers <ethereum@outlook.com> Date: Thu Oct 16 17:08:20 2014 -0700 json was invalid and missing quotes commit0e687cee47
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Thu Oct 16 17:13:24 2014 +0200 Update vmEnvironmentalInfoTest.json commit78a78e2e6c
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 15 14:19:11 2014 +0200 updated genesis_hash commitb315da618b
Merge:7a7e198
0a76a3a
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 14 10:33:26 2014 +0200 Merge pull request #23 from ethers/fix22 numbers should be strings #22 commit0a76a3a312
Author: ethers <ethereum@outlook.com> Date: Mon Oct 13 14:45:30 2014 -0700 numbers should be strings #22 commit1f67385f13
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Sat Oct 11 13:18:00 2014 +0200 Added some MUL tests commit7a7e198395
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Sat Oct 11 13:11:59 2014 +0200 Added some MUL tests commit46eb6283ae
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Sat Oct 11 12:18:13 2014 +0200 tested new opcodes (JUMPDEST,CALLCODE) and created test for CALL/CREATE depth commit8d38d62d10
Author: Nick Savers <nicksavers@gmail.com> Date: Fri Oct 10 18:09:41 2014 +0200 INVALID stops the operation and doesn't cost gas commited6eba7c8e
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 8 19:08:48 2014 +0200 Update + ABA recursive bomb which needs maximum recursion limit of 1024 commit2d72050db1
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 8 14:37:18 2014 +0200 Applied recent protocol changes (PoC7) to existin tests commitdfe66cab3f
Merge:4513623
1a67a96
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 8 11:05:51 2014 +0200 Merge remote-tracking branch 'origin/develop' Conflicts: genesishashestest.json commit1a67a96cff
Merge:a4f5f45
ffd6bc9
Author: vbuterin <v@buterin.com> Date: Tue Oct 7 15:10:23 2014 +0100 Merge pull request #18 from CJentzsch/develop CallToNameRegistratorOutOfGas balance correction commitffd6bc97ad
Merge:a4f5f45
9779d67
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 15:47:34 2014 +0200 Merge remote-tracking branch 'origin/develop' into develop commit9779d67b8c
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 15:45:53 2014 +0200 CallToNameRegistratorOutOfGas balance correction Even if execution fails, the value gets transferred. commita4f5f45228
Merge:49a9f47
b6d7cba
Author: vbuterin <v@buterin.com> Date: Tue Oct 7 14:13:12 2014 +0100 Merge pull request #17 from CJentzsch/develop Added A calls B calls A contracts commitb6d7cba499
Merge:865cb40
49a9f47
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 15:02:51 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit865cb4083d
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 15:02:36 2014 +0200 Added A calls B calls A contracts commit49a9f47aec
Merge:3b0ec43
94a493b
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Tue Oct 7 10:56:17 2014 +0200 Merge pull request #16 from CJentzsch/develop corrected amount of used gas for CallToNameRegistratorOutOfGas commit94a493b0d9
Merge:72853c4
3b0ec43
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 10:51:32 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit72853c4382
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Oct 7 10:51:07 2014 +0200 corrected amount of used gas for CallToNameRegistratorOutOfGas commit3b0ec436e4
Merge:aec3252
222068b
Author: vbuterin <v@buterin.com> Date: Tue Oct 7 05:52:43 2014 +0100 Merge pull request #15 from CJentzsch/develop corrected tests and different style for storage commit222068b9ba
Merge:c169653
aec3252
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Oct 6 21:17:28 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commitc1696531a6
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Oct 6 21:17:09 2014 +0200 corrected tests and different style for storage commitaec3252b8e
Merge:25f9fd5
e17a909
Author: vbuterin <v@buterin.com> Date: Mon Oct 6 09:39:46 2014 +0100 Merge pull request #14 from CJentzsch/develop corrected gas limit in vmSystemOperationsTest commite17a909f70
Merge:33fcab5
25f9fd5
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Oct 6 10:31:51 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit33fcab5727
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Oct 6 10:30:04 2014 +0200 Bug fix, corrected gasLimit in vmSystemOperationsTest commit25f9fd542a
Author: Vitalik Buterin <v@buterin.com> Date: Sat Oct 4 15:47:00 2014 -0400 one more vm test commit2d561a5373
Author: Vitalik Buterin <v@buterin.com> Date: Sat Oct 4 15:15:37 2014 -0400 separated out vmtests commitb0c48fa8d6
Merge:cb8261a
6cae166
Author: vbuterin <v@buterin.com> Date: Sat Oct 4 17:18:02 2014 +0100 Merge pull request #13 from CJentzsch/develop Added comprehensive EVM test suite. All commands are tested. commit6cae166f6f
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 1 15:34:23 2014 +0200 Delete tmp.json commit4ff906fbc2
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Wed Oct 1 14:06:32 2014 +0200 corrected CALLSTATELESS tests commit5b3fee6806
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Sep 29 13:08:44 2014 +0200 Completed vm tests. Added ADDMOD, MULMOD, POST, CALLSTATELESS commit9cdd218083
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Sat Sep 27 21:48:09 2014 +0200 Added IOandFlowOperation-, PushDupSwap- and SystemOperations- tests. Removed empty storage from adresses. commit28ed968b46
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Sep 23 15:49:22 2014 +0200 Added blockInfoTest commitffbd5a35b5
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Tue Sep 23 15:37:52 2014 +0200 Added environmentalInfo- and sha3- test commit54c14f1ff3
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Mon Sep 22 13:06:57 2014 +0200 Added bitwise logic operation test commitd0af113aab
Author: Christoph Jentzsch <jentzsch.software@gmail.com> Date: Sat Sep 20 01:42:51 2014 +0200 Added vm arithmetic test commitcb8261a78b
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Fri Sep 19 13:15:44 2014 +0200 Update genesishashestest.json commit4513623da1
Author: Maran <maran.hidskes@gmail.com> Date: Tue Jul 22 12:24:46 2014 +0200 Update keyaddrtest to be valid JSON commite8cb5c221d
Author: Vitalik Buterin <v@buterin.com> Date: Mon Jul 21 23:30:33 2014 -0400 Added next/prev trie test commit98823c04b3
Author: Vitalik Buterin <v@buterin.com> Date: Mon Jul 14 02:51:31 2014 -0400 Replaced with deterministic test commit357eb21e4d
Author: Vitalik Buterin <v@buterin.com> Date: Sun Jul 13 16:12:56 2014 -0400 Added my own random and namecoin tests (pyethereum) commit00cd0cce8f
Author: Gav Wood <i@gavwood.com> Date: Sat Jul 12 21:20:04 2014 +0200 Output hex strings. commitddfa3af45d
Author: Gav Wood <i@gavwood.com> Date: Thu Jul 10 11:28:35 2014 +0100 Everything a string. commitd659f469a9
Author: Gav Wood <i@gavwood.com> Date: Thu Jul 10 10:16:25 2014 +0100 Code fixes. commit5e83ea8228
Author: Gav Wood <i@gavwood.com> Date: Sun Jul 6 16:17:12 2014 +0200 Prettier VM tests. commita09aae0efe
Author: Gav Wood <i@gavwood.com> Date: Sun Jul 6 15:46:01 2014 +0200 Fix VM tests. commitec9a044a17
Merge:4bb6461
5e0123f
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Fri Jul 4 15:56:52 2014 +0200 Merge pull request #10 from romanman/patch-1 Update vmtests.json commit5e0123fbe1
Author: romanman <roman.mandeleil@gmail.com> Date: Fri Jul 4 10:23:04 2014 +0100 Update vmtests.json commit2b6da2f5f2
Author: romanman <roman.mandeleil@gmail.com> Date: Thu Jul 3 17:45:04 2014 +0100 Update vmtests.json arith testcase updated commit4bb646117d
Merge:bba3898
a33b309
Author: Gav Wood <i@gavwood.com> Date: Wed Jul 2 19:43:22 2014 +0200 Merge branch 'develop' of github.com:/ethereum/tests into develop commitbba38980bd
Author: Gav Wood <i@gavwood.com> Date: Wed Jul 2 19:43:06 2014 +0200 New tests. commita33b309d99
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jul 2 10:14:05 2014 -0400 Testing submodules commit50318217ca
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jul 2 10:10:46 2014 -0400 Testing submodules commit57fa655522
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jul 2 10:09:08 2014 -0400 Testing submodules commitea0eb0a8c8
Author: Gav Wood <i@gavwood.com> Date: Tue Jul 1 15:19:34 2014 +0200 Latest genesis block. commit25bb76b69c
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Mon Jun 30 13:25:04 2014 +0200 Reset commit74c6d8424e
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Mon Jun 30 12:10:06 2014 +0200 Updated wrong test commit9ea3a60291
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Sat Jun 28 18:48:28 2014 +0200 Fixed roots commit5fc3ac0e92
Author: Gav Wood <i@gavwood.com> Date: Sat Jun 28 18:40:06 2014 +0200 Simple hex test. commitedd3a00c2a
Author: Gav Wood <i@gavwood.com> Date: Sat Jun 28 18:22:18 2014 +0200 Additional test for jeff. Now use the 0x... notation. commit5021e0dd83
Author: Gav Wood <i@gavwood.com> Date: Fri Jun 27 21:35:26 2014 +0200 VM test framework updated. commitc818d13202
Author: Gav Wood <i@gavwood.com> Date: Fri Jun 27 18:18:24 2014 +0200 Removed arrays from Trie tests JSON as per conformance guide and changed vocabulary to match other tests. VM test updates. commit714770ffb3
Author: Gav Wood <i@gavwood.com> Date: Wed Jun 11 11:32:42 2014 +0100 Added Gav's new address. commit9345bc13d4
Merge:a2257f3
78576dd
Author: Gav Wood <i@gavwood.com> Date: Fri May 30 17:50:38 2014 +0200 Merge branch 'master' of github.com:ethereum/tests into develop commita2257f3471
Author: Gav Wood <i@gavwood.com> Date: Fri May 30 17:50:18 2014 +0200 VM tests. commit78576dd3d3
Author: Heiko Heiko <heiko@heiko.org> Date: Fri May 30 17:19:09 2014 +0200 changes based on new account structure nonce, balance, storage, code commit125839e848
Merge:42e14ec
356a329
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Thu May 22 09:58:45 2014 +0200 Merge pull request #5 from bkirwi/master Fix invalid JSON (removed trailing comma) and add test names commit356a3296bc
Author: Ben Kirwin <ben@kirw.in> Date: Thu May 22 00:20:48 2014 -0400 Add some arbitrary test names This should now conform to the format specified in the README. commit42e14ec54f
Author: Chen Houwu <chenhouwu@gmail.com> Date: Wed May 21 23:27:40 2014 +0800 revert to correct data commit4300197a74
Author: Chen Houwu <chenhouwu@gmail.com> Date: Wed May 21 22:42:23 2014 +0800 fix: wrong sha3 hash because of the wrong rlp hex commita0d01b1a0b
Author: Chen Houwu <chenhouwu@gmail.com> Date: Wed May 21 22:29:53 2014 +0800 fix: wrong rlp hex commit6bc2fc7405
Merge:66bc366
c31a93c
Author: Jeffrey Wilcke <obscuren@users.noreply.github.com> Date: Wed May 21 14:11:37 2014 +0200 Merge pull request #4 from ethers/master fix file name that seems to have been a typo commitc31a93c27a
Author: ethers <ethereum@outlook.com> Date: Tue May 20 15:42:39 2014 -0700 fix file name that seems to have been a typo commit66bc3665c1
Author: Heiko Heiko <heiko@heiko.org> Date: Tue May 20 17:36:35 2014 +0200 fix: represent integers as strings commitede5499da6
Author: Heiko Heiko <heiko@heiko.org> Date: Tue May 20 17:21:09 2014 +0200 add: current initial alloc and genesis hashes commit5131429abb
Author: Ben Kirwin <ben@kirw.in> Date: Mon May 19 11:18:31 2014 -0400 Delete a comma This should now be parseable as JSON. commitf44a859331
Author: Chen Houwu <chenhouwu@gmail.com> Date: Sun May 18 15:04:42 2014 +0800 add: case when value is long, ensure it's not get rlp encoded as node commite1ae4ad449
Author: Gav Wood <i@gavwood.com> Date: Mon May 12 14:40:47 2014 +0100 PoC-5 VM tests. commit2b6c136dda
Author: Vitalik Buterin <v@buterin.com> Date: Sun May 11 21:42:41 2014 -0400 Moved txt to json commitcbccbf977c
Merge:edbb8d4
45a0974
Author: Vitalik Buterin <v@buterin.com> Date: Thu May 8 21:54:48 2014 -0400 New commit commitedbb8d407e
Author: Vitalik Buterin <v@buterin.com> Date: Tue May 6 16:53:43 2014 -0400 Removed unneeded test, added new tests commit45a0974f6f
Merge:15dd8fd
5fd2a98
Author: Gav Wood <i@gavwood.com> Date: Sun Apr 27 12:53:47 2014 +0100 Merge pull request #3 from autolycus/develop Fixed formatting and added test cases commit5fd2a98fcb
Author: Carl Allendorph <callendorph@gmail.com> Date: Sat Apr 19 13:26:14 2014 -0700 Added some new test cases for the rlp encoding. commit4ba150954e
Author: Carl Allendorph <callendorph@gmail.com> Date: Sat Apr 19 12:48:42 2014 -0700 Converted spaces to tabs to be compliant with the coding standards defined in cpp-ethereum commit15dd8fd794
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 28 12:54:47 2014 +0000 RLP tests and Trie updates. commit33f80fef21
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 28 11:39:35 2014 +0000 Hex encode tests done. commite1f5e12abb
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 28 11:22:49 2014 +0000 Fix RLP tests. commitf87ce15ad2
Author: Gav Wood <i@gavwood.com> Date: Thu Feb 27 13:28:11 2014 +0000 Fix empty string. commitc006ed4ffd
Author: Gav Wood <i@gavwood.com> Date: Mon Feb 24 10:24:39 2014 +0000 Tests fix. commit510ff56363
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 21 18:54:08 2014 +0000 Updated the tests. commita0ec843832
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 21 18:49:24 2014 +0000 Moved over to new format, but RLP tests still need updating. commit660cd26f31
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 21 18:35:51 2014 +0000 More docs. commit6ad14c1a15
Author: Gav Wood <i@gavwood.com> Date: Fri Feb 21 18:33:39 2014 +0000 Added VM test suite. Added TODO. Renamed old files. commitf91ad7b385
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jan 8 11:26:58 2014 -0500 update trie algorithm commit6da2954462
Merge:cc42246
131c610
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jan 8 08:15:38 2014 -0500 merge commitcc4224675f
Author: Vitalik Buterin <v@buterin.com> Date: Tue Jan 7 14:35:26 2014 -0500 Updated trie test commit131c610da6
Merge:121632b
7613302
Author: vbuterin <v@buterin.com> Date: Wed Jan 1 06:40:54 2014 -0800 Merge pull request #1 from obscuren/master Update trietest.txt commit7613302b49
Author: obscuren <obscuren@users.noreply.github.com> Date: Wed Jan 1 15:25:21 2014 +0100 Update trietest.txt New proposed explanatory format commit121632bedd
Author: Vitalik Buterin <v@buterin.com> Date: Wed Jan 1 08:26:18 2014 -0500 Added obscure's tests commitef6c5506c3
Author: Vitalik Buterin <v@buterin.com> Date: Tue Dec 31 19:04:48 2013 -0500 Fixed tests a bit commit345e4bcfef
Merge:2c81698
e4bbea4
Author: Vitalik Buterin <v@buterin.com> Date: Tue Dec 31 15:52:46 2013 -0500 Merge branch 'master' of github.com:ethereum/tests commit2c81698f31
Author: Vitalik Buterin <v@buterin.com> Date: Mon Dec 30 21:09:40 2013 -0500 Added first three tests commite4bbea400f
Author: vbuterin <v@buterin.com> Date: Mon Dec 30 18:09:03 2013 -0800 Initial commit
946 lines
20 KiB
Go
946 lines
20 KiB
Go
package vm
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/ethutil"
|
|
"github.com/ethereum/go-ethereum/state"
|
|
)
|
|
|
|
type DebugVm struct {
|
|
env Environment
|
|
|
|
logTy byte
|
|
logStr string
|
|
|
|
err error
|
|
|
|
// Debugging
|
|
Dbg Debugger
|
|
|
|
BreakPoints []int64
|
|
Stepping bool
|
|
Fn string
|
|
|
|
Recoverable bool
|
|
|
|
depth int
|
|
}
|
|
|
|
func NewDebugVm(env Environment) *DebugVm {
|
|
lt := LogTyPretty
|
|
if ethutil.Config.Diff {
|
|
lt = LogTyDiff
|
|
}
|
|
|
|
return &DebugVm{env: env, logTy: lt, Recoverable: true}
|
|
}
|
|
|
|
func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
self.depth++
|
|
|
|
if self.Recoverable {
|
|
// Recover from any require exception
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
self.Endl()
|
|
|
|
ret = closure.Return(nil)
|
|
|
|
err = fmt.Errorf("%v", r)
|
|
// No error should be set. Recover is used with require
|
|
// Is this too error prone?
|
|
}
|
|
}()
|
|
}
|
|
|
|
var (
|
|
op OpCode
|
|
|
|
mem = &Memory{}
|
|
stack = NewStack()
|
|
pc = big.NewInt(0)
|
|
step = 0
|
|
prevStep = 0
|
|
statedb = self.env.State()
|
|
require = func(m int) {
|
|
if stack.Len() < m {
|
|
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
|
|
}
|
|
}
|
|
|
|
jump = func(pos *big.Int) {
|
|
p := int(pos.Int64())
|
|
|
|
self.Printf(" ~> %v", pos)
|
|
// Return to start
|
|
if p == 0 {
|
|
pc = big.NewInt(0)
|
|
} else {
|
|
nop := OpCode(closure.GetOp(p - 1))
|
|
if nop != JUMPDEST {
|
|
panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
|
|
}
|
|
|
|
pc = pos
|
|
}
|
|
|
|
self.Endl()
|
|
}
|
|
)
|
|
|
|
// Debug hook
|
|
if self.Dbg != nil {
|
|
self.Dbg.SetCode(closure.Code)
|
|
}
|
|
|
|
// Don't bother with the execution if there's no code.
|
|
if len(closure.Code) == 0 {
|
|
return closure.Return(nil), nil
|
|
}
|
|
|
|
vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, closure.Address(), closure.Gas, closure.Args)
|
|
|
|
for {
|
|
prevStep = step
|
|
// The base for all big integer arithmetic
|
|
base := new(big.Int)
|
|
|
|
step++
|
|
// Get the memory location of pc
|
|
op = closure.GetOp(int(pc.Uint64()))
|
|
|
|
// XXX Leave this Println intact. Don't change this to the log system.
|
|
// Used for creating diffs between implementations
|
|
if self.logTy == LogTyDiff {
|
|
switch op {
|
|
case STOP, RETURN, SUICIDE:
|
|
statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
|
|
value.Decode()
|
|
fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
|
|
})
|
|
}
|
|
|
|
b := pc.Bytes()
|
|
if len(b) == 0 {
|
|
b = []byte{0}
|
|
}
|
|
|
|
fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
|
|
}
|
|
|
|
gas := new(big.Int)
|
|
addStepGasUsage := func(amount *big.Int) {
|
|
if amount.Cmp(ethutil.Big0) >= 0 {
|
|
gas.Add(gas, amount)
|
|
}
|
|
}
|
|
|
|
addStepGasUsage(GasStep)
|
|
|
|
var newMemSize *big.Int = ethutil.Big0
|
|
// Stack Check, memory resize & gas phase
|
|
switch op {
|
|
// Stack checks only
|
|
case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1
|
|
require(1)
|
|
case ADD, SUB, DIV, SDIV, MOD, SMOD, EXP, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE: // 2
|
|
require(2)
|
|
case ADDMOD, MULMOD: // 3
|
|
require(3)
|
|
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
|
|
n := int(op - SWAP1 + 2)
|
|
require(n)
|
|
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
|
n := int(op - DUP1 + 1)
|
|
require(n)
|
|
case LOG0, LOG1, LOG2, LOG3, LOG4:
|
|
n := int(op - LOG0)
|
|
require(n + 2)
|
|
|
|
mSize, mStart := stack.Peekn()
|
|
gas.Set(GasLog)
|
|
addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
|
|
addStepGasUsage(new(big.Int).Add(mSize, mStart))
|
|
// Gas only
|
|
case STOP:
|
|
gas.Set(ethutil.Big0)
|
|
case SUICIDE:
|
|
require(1)
|
|
|
|
gas.Set(ethutil.Big0)
|
|
case SLOAD:
|
|
require(1)
|
|
|
|
gas.Set(GasSLoad)
|
|
// Memory resize & Gas
|
|
case SSTORE:
|
|
require(2)
|
|
|
|
var mult *big.Int
|
|
y, x := stack.Peekn()
|
|
val := closure.GetStorage(x)
|
|
if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
|
|
// 0 => non 0
|
|
mult = ethutil.Big3
|
|
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
|
|
statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
|
|
|
|
mult = ethutil.Big0
|
|
} else {
|
|
// non 0 => non 0
|
|
mult = ethutil.Big1
|
|
}
|
|
gas.Set(new(big.Int).Mul(mult, GasSStore))
|
|
case BALANCE:
|
|
require(1)
|
|
gas.Set(GasBalance)
|
|
case MSTORE:
|
|
require(2)
|
|
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
|
case MLOAD:
|
|
require(1)
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
|
case MSTORE8:
|
|
require(2)
|
|
newMemSize = calcMemSize(stack.Peek(), u256(1))
|
|
case RETURN:
|
|
require(2)
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
|
case SHA3:
|
|
require(2)
|
|
|
|
gas.Set(GasSha)
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
|
case CALLDATACOPY:
|
|
require(2)
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
|
|
case CODECOPY:
|
|
require(3)
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
|
|
case EXTCODECOPY:
|
|
require(4)
|
|
|
|
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
|
|
case CALL, CALLCODE:
|
|
require(7)
|
|
gas.Set(GasCall)
|
|
addStepGasUsage(stack.data[stack.Len()-1])
|
|
|
|
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
|
|
y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
|
|
|
|
newMemSize = ethutil.BigMax(x, y)
|
|
case CREATE:
|
|
require(3)
|
|
gas.Set(GasCreate)
|
|
|
|
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
|
|
}
|
|
|
|
if newMemSize.Cmp(ethutil.Big0) > 0 {
|
|
newMemSize.Add(newMemSize, u256(31))
|
|
newMemSize.Div(newMemSize, u256(32))
|
|
newMemSize.Mul(newMemSize, u256(32))
|
|
|
|
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
|
|
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
|
|
memGasUsage.Mul(GasMemory, memGasUsage)
|
|
memGasUsage.Div(memGasUsage, u256(32))
|
|
|
|
addStepGasUsage(memGasUsage)
|
|
}
|
|
}
|
|
|
|
self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
|
|
self.Printf(" (g) %-3v (%v)", gas, closure.Gas)
|
|
|
|
if !closure.UseGas(gas) {
|
|
self.Endl()
|
|
|
|
tmp := new(big.Int).Set(closure.Gas)
|
|
|
|
closure.UseGas(closure.Gas)
|
|
|
|
return closure.Return(nil), OOG(gas, tmp)
|
|
}
|
|
|
|
mem.Resize(newMemSize.Uint64())
|
|
|
|
switch op {
|
|
// 0x20 range
|
|
case ADD:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v + %v", y, x)
|
|
|
|
base.Add(y, x)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
// Pop result back on the stack
|
|
stack.Push(base)
|
|
case SUB:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v - %v", y, x)
|
|
|
|
base.Sub(y, x)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
// Pop result back on the stack
|
|
stack.Push(base)
|
|
case MUL:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v * %v", y, x)
|
|
|
|
base.Mul(y, x)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
// Pop result back on the stack
|
|
stack.Push(base)
|
|
case DIV:
|
|
x, y := stack.Pop(), stack.Pop()
|
|
self.Printf(" %v / %v", x, y)
|
|
|
|
if y.Cmp(ethutil.Big0) != 0 {
|
|
base.Div(x, y)
|
|
}
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
// Pop result back on the stack
|
|
stack.Push(base)
|
|
case SDIV:
|
|
x, y := S256(stack.Pop()), S256(stack.Pop())
|
|
|
|
self.Printf(" %v / %v", x, y)
|
|
|
|
if y.Cmp(ethutil.Big0) == 0 {
|
|
base.Set(ethutil.Big0)
|
|
} else {
|
|
n := new(big.Int)
|
|
if new(big.Int).Mul(x, y).Cmp(ethutil.Big0) < 0 {
|
|
n.SetInt64(-1)
|
|
} else {
|
|
n.SetInt64(1)
|
|
}
|
|
|
|
base.Div(x.Abs(x), y.Abs(y)).Mul(base, n)
|
|
|
|
U256(base)
|
|
}
|
|
|
|
self.Printf(" = %v", base)
|
|
stack.Push(base)
|
|
case MOD:
|
|
x, y := stack.Pop(), stack.Pop()
|
|
|
|
self.Printf(" %v %% %v", x, y)
|
|
|
|
if y.Cmp(ethutil.Big0) == 0 {
|
|
base.Set(ethutil.Big0)
|
|
} else {
|
|
base.Mod(x, y)
|
|
}
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
stack.Push(base)
|
|
case SMOD:
|
|
x, y := S256(stack.Pop()), S256(stack.Pop())
|
|
|
|
self.Printf(" %v %% %v", x, y)
|
|
|
|
if y.Cmp(ethutil.Big0) == 0 {
|
|
base.Set(ethutil.Big0)
|
|
} else {
|
|
n := new(big.Int)
|
|
if x.Cmp(ethutil.Big0) < 0 {
|
|
n.SetInt64(-1)
|
|
} else {
|
|
n.SetInt64(1)
|
|
}
|
|
|
|
base.Mod(x.Abs(x), y.Abs(y)).Mul(base, n)
|
|
|
|
U256(base)
|
|
}
|
|
|
|
self.Printf(" = %v", base)
|
|
stack.Push(base)
|
|
|
|
case EXP:
|
|
x, y := stack.Popn()
|
|
|
|
self.Printf(" %v ** %v", y, x)
|
|
|
|
base.Exp(y, x, Pow256)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
|
|
stack.Push(base)
|
|
case SIGNEXTEND:
|
|
back := stack.Pop().Uint64()
|
|
if back < 31 {
|
|
bit := uint(back*8 + 7)
|
|
num := stack.Pop()
|
|
mask := new(big.Int).Lsh(ethutil.Big1, bit)
|
|
mask.Sub(mask, ethutil.Big1)
|
|
if ethutil.BitTest(num, int(bit)) {
|
|
num.Or(num, mask.Not(mask))
|
|
} else {
|
|
num.And(num, mask)
|
|
}
|
|
stack.Push(num)
|
|
}
|
|
case NOT:
|
|
base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1)
|
|
|
|
// Not needed
|
|
//base = U256(base)
|
|
|
|
stack.Push(base)
|
|
case LT:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v < %v", y, x)
|
|
// x < y
|
|
if y.Cmp(x) < 0 {
|
|
stack.Push(ethutil.BigTrue)
|
|
} else {
|
|
stack.Push(ethutil.BigFalse)
|
|
}
|
|
case GT:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v > %v", y, x)
|
|
|
|
// x > y
|
|
if y.Cmp(x) > 0 {
|
|
stack.Push(ethutil.BigTrue)
|
|
} else {
|
|
stack.Push(ethutil.BigFalse)
|
|
}
|
|
|
|
case SLT:
|
|
y, x := S256(stack.Pop()), S256(stack.Pop())
|
|
self.Printf(" %v < %v", y, x)
|
|
// x < y
|
|
if y.Cmp(S256(x)) < 0 {
|
|
stack.Push(ethutil.BigTrue)
|
|
} else {
|
|
stack.Push(ethutil.BigFalse)
|
|
}
|
|
case SGT:
|
|
y, x := S256(stack.Pop()), S256(stack.Pop())
|
|
self.Printf(" %v > %v", y, x)
|
|
|
|
// x > y
|
|
if y.Cmp(x) > 0 {
|
|
stack.Push(ethutil.BigTrue)
|
|
} else {
|
|
stack.Push(ethutil.BigFalse)
|
|
}
|
|
|
|
case EQ:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v == %v", y, x)
|
|
|
|
// x == y
|
|
if x.Cmp(y) == 0 {
|
|
stack.Push(ethutil.BigTrue)
|
|
} else {
|
|
stack.Push(ethutil.BigFalse)
|
|
}
|
|
case ISZERO:
|
|
x := stack.Pop()
|
|
if x.Cmp(ethutil.BigFalse) > 0 {
|
|
stack.Push(ethutil.BigFalse)
|
|
} else {
|
|
stack.Push(ethutil.BigTrue)
|
|
}
|
|
|
|
// 0x10 range
|
|
case AND:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v & %v", y, x)
|
|
|
|
stack.Push(base.And(y, x))
|
|
case OR:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v | %v", y, x)
|
|
|
|
stack.Push(base.Or(y, x))
|
|
case XOR:
|
|
x, y := stack.Popn()
|
|
self.Printf(" %v ^ %v", y, x)
|
|
|
|
stack.Push(base.Xor(y, x))
|
|
case BYTE:
|
|
val, th := stack.Popn()
|
|
|
|
if th.Cmp(big.NewInt(32)) < 0 {
|
|
byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
|
|
|
|
base.Set(byt)
|
|
} else {
|
|
base.Set(ethutil.BigFalse)
|
|
}
|
|
|
|
self.Printf(" => 0x%x", base.Bytes())
|
|
|
|
stack.Push(base)
|
|
case ADDMOD:
|
|
|
|
x := stack.Pop()
|
|
y := stack.Pop()
|
|
z := stack.Pop()
|
|
|
|
base.Add(x, y)
|
|
base.Mod(base, z)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
|
|
stack.Push(base)
|
|
case MULMOD:
|
|
|
|
x := stack.Pop()
|
|
y := stack.Pop()
|
|
z := stack.Pop()
|
|
|
|
base.Mul(x, y)
|
|
base.Mod(base, z)
|
|
|
|
U256(base)
|
|
|
|
self.Printf(" = %v", base)
|
|
|
|
stack.Push(base)
|
|
|
|
// 0x20 range
|
|
case SHA3:
|
|
size, offset := stack.Popn()
|
|
data := crypto.Sha3(mem.Get(offset.Int64(), size.Int64()))
|
|
|
|
stack.Push(ethutil.BigD(data))
|
|
|
|
self.Printf(" => %x", data)
|
|
// 0x30 range
|
|
case ADDRESS:
|
|
stack.Push(ethutil.BigD(closure.Address()))
|
|
|
|
self.Printf(" => %x", closure.Address())
|
|
case BALANCE:
|
|
|
|
addr := stack.Pop().Bytes()
|
|
balance := statedb.GetBalance(addr)
|
|
|
|
stack.Push(balance)
|
|
|
|
self.Printf(" => %v (%x)", balance, addr)
|
|
case ORIGIN:
|
|
origin := self.env.Origin()
|
|
|
|
stack.Push(ethutil.BigD(origin))
|
|
|
|
self.Printf(" => %x", origin)
|
|
case CALLER:
|
|
caller := closure.caller.Address()
|
|
stack.Push(ethutil.BigD(caller))
|
|
|
|
self.Printf(" => %x", caller)
|
|
case CALLVALUE:
|
|
value := closure.exe.value
|
|
|
|
stack.Push(value)
|
|
|
|
self.Printf(" => %v", value)
|
|
case CALLDATALOAD:
|
|
var (
|
|
offset = stack.Pop()
|
|
data = make([]byte, 32)
|
|
lenData = big.NewInt(int64(len(closure.Args)))
|
|
)
|
|
|
|
if lenData.Cmp(offset) >= 0 {
|
|
length := new(big.Int).Add(offset, ethutil.Big32)
|
|
length = ethutil.BigMin(length, lenData)
|
|
|
|
copy(data, closure.Args[offset.Int64():length.Int64()])
|
|
}
|
|
|
|
self.Printf(" => 0x%x", data)
|
|
|
|
stack.Push(ethutil.BigD(data))
|
|
case CALLDATASIZE:
|
|
l := int64(len(closure.Args))
|
|
stack.Push(big.NewInt(l))
|
|
|
|
self.Printf(" => %d", l)
|
|
case CALLDATACOPY:
|
|
var (
|
|
size = int64(len(closure.Args))
|
|
mOff = stack.Pop().Int64()
|
|
cOff = stack.Pop().Int64()
|
|
l = stack.Pop().Int64()
|
|
)
|
|
|
|
if cOff > size {
|
|
cOff = 0
|
|
l = 0
|
|
} else if cOff+l > size {
|
|
l = 0
|
|
}
|
|
|
|
code := closure.Args[cOff : cOff+l]
|
|
|
|
mem.Set(mOff, l, code)
|
|
case CODESIZE, EXTCODESIZE:
|
|
var code []byte
|
|
if op == EXTCODESIZE {
|
|
addr := stack.Pop().Bytes()
|
|
|
|
code = statedb.GetCode(addr)
|
|
} else {
|
|
code = closure.Code
|
|
}
|
|
|
|
l := big.NewInt(int64(len(code)))
|
|
stack.Push(l)
|
|
|
|
self.Printf(" => %d", l)
|
|
case CODECOPY, EXTCODECOPY:
|
|
var code []byte
|
|
if op == EXTCODECOPY {
|
|
addr := stack.Pop().Bytes()
|
|
|
|
code = statedb.GetCode(addr)
|
|
} else {
|
|
code = closure.Code
|
|
}
|
|
|
|
var (
|
|
size = int64(len(code))
|
|
mOff = stack.Pop().Int64()
|
|
cOff = stack.Pop().Int64()
|
|
l = stack.Pop().Int64()
|
|
)
|
|
|
|
if cOff > size {
|
|
cOff = 0
|
|
l = 0
|
|
} else if cOff+l > size {
|
|
l = 0
|
|
}
|
|
|
|
codeCopy := code[cOff : cOff+l]
|
|
|
|
mem.Set(mOff, l, codeCopy)
|
|
case GASPRICE:
|
|
stack.Push(closure.Price)
|
|
|
|
self.Printf(" => %v", closure.Price)
|
|
|
|
// 0x40 range
|
|
case PREVHASH:
|
|
prevHash := self.env.PrevHash()
|
|
|
|
stack.Push(ethutil.BigD(prevHash))
|
|
|
|
self.Printf(" => 0x%x", prevHash)
|
|
case COINBASE:
|
|
coinbase := self.env.Coinbase()
|
|
|
|
stack.Push(ethutil.BigD(coinbase))
|
|
|
|
self.Printf(" => 0x%x", coinbase)
|
|
case TIMESTAMP:
|
|
time := self.env.Time()
|
|
|
|
stack.Push(big.NewInt(time))
|
|
|
|
self.Printf(" => 0x%x", time)
|
|
case NUMBER:
|
|
number := self.env.BlockNumber()
|
|
|
|
stack.Push(number)
|
|
|
|
self.Printf(" => 0x%x", number.Bytes())
|
|
case DIFFICULTY:
|
|
difficulty := self.env.Difficulty()
|
|
|
|
stack.Push(difficulty)
|
|
|
|
self.Printf(" => 0x%x", difficulty.Bytes())
|
|
case GASLIMIT:
|
|
stack.Push(self.env.GasLimit())
|
|
|
|
// 0x50 range
|
|
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:
|
|
a := big.NewInt(int64(op) - int64(PUSH1) + 1)
|
|
pc.Add(pc, ethutil.Big1)
|
|
data := closure.Gets(pc, a)
|
|
val := ethutil.BigD(data.Bytes())
|
|
// Push value to stack
|
|
stack.Push(val)
|
|
pc.Add(pc, a.Sub(a, big.NewInt(1)))
|
|
|
|
step += int(op) - int(PUSH1) + 1
|
|
|
|
self.Printf(" => 0x%x", data.Bytes())
|
|
case POP:
|
|
stack.Pop()
|
|
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
|
n := int(op - DUP1 + 1)
|
|
v := stack.Dupn(n)
|
|
|
|
self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
|
|
|
|
if OpCode(closure.Get(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.Get(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
|
|
fmt.Println(toValue(v))
|
|
}
|
|
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
|
|
n := int(op - SWAP1 + 2)
|
|
x, y := stack.Swapn(n)
|
|
|
|
self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
|
|
case LOG0, LOG1, LOG2, LOG3, LOG4:
|
|
n := int(op - LOG0)
|
|
topics := make([][]byte, n)
|
|
mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64()
|
|
data := mem.Geti(mStart, mSize)
|
|
for i := 0; i < n; i++ {
|
|
topics[i] = stack.Pop().Bytes()
|
|
}
|
|
self.env.AddLog(state.Log{closure.Address(), topics, data})
|
|
case MLOAD:
|
|
offset := stack.Pop()
|
|
val := ethutil.BigD(mem.Get(offset.Int64(), 32))
|
|
stack.Push(val)
|
|
|
|
self.Printf(" => 0x%x", val.Bytes())
|
|
case MSTORE: // Store the value at stack top-1 in to memory at location stack top
|
|
// Pop value of the stack
|
|
val, mStart := stack.Popn()
|
|
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
|
|
|
|
self.Printf(" => 0x%x", val)
|
|
case MSTORE8:
|
|
off := stack.Pop()
|
|
val := stack.Pop()
|
|
|
|
mem.store[off.Int64()] = byte(val.Int64() & 0xff)
|
|
|
|
self.Printf(" => [%v] 0x%x", off, val)
|
|
case SLOAD:
|
|
loc := stack.Pop()
|
|
val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes()))
|
|
stack.Push(val)
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
|
case SSTORE:
|
|
val, loc := stack.Popn()
|
|
statedb.SetState(closure.Address(), loc.Bytes(), val)
|
|
|
|
// Debug sessions are allowed to run without message
|
|
if closure.message != nil {
|
|
closure.message.AddStorageChange(loc.Bytes())
|
|
}
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
|
case JUMP:
|
|
|
|
jump(stack.Pop())
|
|
|
|
continue
|
|
case JUMPI:
|
|
cond, pos := stack.Popn()
|
|
|
|
if cond.Cmp(ethutil.BigTrue) >= 0 {
|
|
jump(pos)
|
|
|
|
continue
|
|
}
|
|
|
|
case JUMPDEST:
|
|
case PC:
|
|
stack.Push(pc)
|
|
case MSIZE:
|
|
stack.Push(big.NewInt(int64(mem.Len())))
|
|
case GAS:
|
|
stack.Push(closure.Gas)
|
|
// 0x60 range
|
|
case CREATE:
|
|
|
|
var (
|
|
err error
|
|
value = stack.Pop()
|
|
size, offset = stack.Popn()
|
|
input = mem.Get(offset.Int64(), size.Int64())
|
|
gas = new(big.Int).Set(closure.Gas)
|
|
|
|
// Snapshot the current stack so we are able to
|
|
// revert back to it later.
|
|
//snapshot = self.env.State().Copy()
|
|
)
|
|
|
|
// Generate a new address
|
|
n := statedb.GetNonce(closure.Address())
|
|
addr := crypto.CreateAddress(closure.Address(), n)
|
|
statedb.SetNonce(closure.Address(), n+1)
|
|
|
|
self.Printf(" (*) %x", addr).Endl()
|
|
|
|
closure.UseGas(closure.Gas)
|
|
|
|
msg := NewExecution(self, addr, input, gas, closure.Price, value)
|
|
ret, err := msg.Create(closure)
|
|
if err != nil {
|
|
stack.Push(ethutil.BigFalse)
|
|
|
|
// Revert the state as it was before.
|
|
//self.env.State().Set(snapshot)
|
|
|
|
self.Printf("CREATE err %v", err)
|
|
} else {
|
|
msg.object.Code = ret
|
|
|
|
stack.Push(ethutil.BigD(addr))
|
|
}
|
|
|
|
self.Endl()
|
|
|
|
// Debug hook
|
|
if self.Dbg != nil {
|
|
self.Dbg.SetCode(closure.Code)
|
|
}
|
|
case CALL, CALLCODE:
|
|
self.Endl()
|
|
|
|
gas := stack.Pop()
|
|
// Pop gas and value of the stack.
|
|
value, addr := stack.Popn()
|
|
// Pop input size and offset
|
|
inSize, inOffset := stack.Popn()
|
|
// Pop return size and offset
|
|
retSize, retOffset := stack.Popn()
|
|
|
|
// Get the arguments from the memory
|
|
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
|
|
|
var executeAddr []byte
|
|
if op == CALLCODE {
|
|
executeAddr = closure.Address()
|
|
} else {
|
|
executeAddr = addr.Bytes()
|
|
}
|
|
|
|
msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
|
|
ret, err := msg.Exec(addr.Bytes(), closure)
|
|
if err != nil {
|
|
stack.Push(ethutil.BigFalse)
|
|
|
|
vmlogger.Debugln(err)
|
|
} else {
|
|
stack.Push(ethutil.BigTrue)
|
|
|
|
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
|
}
|
|
self.Printf("resume %x", closure.Address())
|
|
|
|
// Debug hook
|
|
if self.Dbg != nil {
|
|
self.Dbg.SetCode(closure.Code)
|
|
}
|
|
|
|
case RETURN:
|
|
size, offset := stack.Popn()
|
|
ret := mem.Get(offset.Int64(), size.Int64())
|
|
|
|
self.Printf(" => (%d) 0x%x", len(ret), ret).Endl()
|
|
|
|
return closure.Return(ret), nil
|
|
case SUICIDE:
|
|
|
|
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
|
|
|
receiver.AddAmount(statedb.GetBalance(closure.Address()))
|
|
statedb.Delete(closure.Address())
|
|
|
|
fallthrough
|
|
case STOP: // Stop the closure
|
|
self.Endl()
|
|
|
|
return closure.Return(nil), nil
|
|
default:
|
|
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op)
|
|
|
|
//panic(fmt.Sprintf("Invalid opcode %x", op))
|
|
closure.ReturnGas(big.NewInt(1), nil)
|
|
|
|
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op)
|
|
}
|
|
|
|
pc.Add(pc, ethutil.Big1)
|
|
|
|
self.Endl()
|
|
|
|
if self.Dbg != nil {
|
|
for _, instrNo := range self.Dbg.BreakPoints() {
|
|
if pc.Cmp(big.NewInt(instrNo)) == 0 {
|
|
self.Stepping = true
|
|
|
|
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
|
return nil, nil
|
|
}
|
|
} else if self.Stepping {
|
|
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
|
return nil, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func (self *DebugVm) Printf(format string, v ...interface{}) VirtualMachine {
|
|
if self.logTy == LogTyPretty {
|
|
self.logStr += fmt.Sprintf(format, v...)
|
|
}
|
|
|
|
return self
|
|
}
|
|
|
|
func (self *DebugVm) Endl() VirtualMachine {
|
|
if self.logTy == LogTyPretty {
|
|
vmlogger.Debugln(self.logStr)
|
|
self.logStr = ""
|
|
}
|
|
|
|
return self
|
|
}
|
|
|
|
func (self *DebugVm) Env() Environment {
|
|
return self.env
|
|
}
|
|
|
|
func (self *DebugVm) Depth() int {
|
|
return self.depth
|
|
}
|