vm_test_util.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package tests
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "math/big"
  7. "strconv"
  8. "testing"
  9. "github.com/ethereum/go-ethereum/common"
  10. "github.com/ethereum/go-ethereum/core"
  11. "github.com/ethereum/go-ethereum/core/state"
  12. "github.com/ethereum/go-ethereum/core/types"
  13. "github.com/ethereum/go-ethereum/core/vm"
  14. "github.com/ethereum/go-ethereum/crypto"
  15. "github.com/ethereum/go-ethereum/ethdb"
  16. // "github.com/ethereum/go-ethereum/logger"
  17. )
  18. type Account struct {
  19. Balance string
  20. Code string
  21. Nonce string
  22. Storage map[string]string
  23. }
  24. type Log struct {
  25. AddressF string `json:"address"`
  26. DataF string `json:"data"`
  27. TopicsF []string `json:"topics"`
  28. BloomF string `json:"bloom"`
  29. }
  30. func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) }
  31. func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) }
  32. func (self Log) RlpData() interface{} { return nil }
  33. func (self Log) Topics() [][]byte {
  34. t := make([][]byte, len(self.TopicsF))
  35. for i, topic := range self.TopicsF {
  36. t[i] = common.Hex2Bytes(topic)
  37. }
  38. return t
  39. }
  40. func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject {
  41. obj := state.NewStateObject(common.HexToAddress(addr), db)
  42. obj.SetBalance(common.Big(account.Balance))
  43. if common.IsHex(account.Code) {
  44. account.Code = account.Code[2:]
  45. }
  46. obj.SetCode(common.Hex2Bytes(account.Code))
  47. obj.SetNonce(common.Big(account.Nonce).Uint64())
  48. return obj
  49. }
  50. type VmEnv struct {
  51. CurrentCoinbase string
  52. CurrentDifficulty string
  53. CurrentGasLimit string
  54. CurrentNumber string
  55. CurrentTimestamp interface{}
  56. PreviousHash string
  57. }
  58. type VmTest struct {
  59. Callcreates interface{}
  60. //Env map[string]string
  61. Env VmEnv
  62. Exec map[string]string
  63. Transaction map[string]string
  64. Logs []Log
  65. Gas string
  66. Out string
  67. Post map[string]Account
  68. Pre map[string]Account
  69. PostStateRoot string
  70. }
  71. func RunVmTest(p string, t *testing.T) {
  72. tests := make(map[string]VmTest)
  73. CreateFileTests(t, p, &tests)
  74. for name, test := range tests {
  75. /*
  76. vm.Debug = true
  77. glog.SetV(4)
  78. glog.SetToStderr(true)
  79. if name != "Call50000_sha256" {
  80. continue
  81. }
  82. */
  83. db, _ := ethdb.NewMemDatabase()
  84. statedb := state.New(common.Hash{}, db)
  85. for addr, account := range test.Pre {
  86. obj := StateObjectFromAccount(db, addr, account)
  87. statedb.SetStateObject(obj)
  88. for a, v := range account.Storage {
  89. obj.SetState(common.HexToHash(a), common.HexToHash(v))
  90. }
  91. }
  92. // XXX Yeah, yeah...
  93. env := make(map[string]string)
  94. env["currentCoinbase"] = test.Env.CurrentCoinbase
  95. env["currentDifficulty"] = test.Env.CurrentDifficulty
  96. env["currentGasLimit"] = test.Env.CurrentGasLimit
  97. env["currentNumber"] = test.Env.CurrentNumber
  98. env["previousHash"] = test.Env.PreviousHash
  99. if n, ok := test.Env.CurrentTimestamp.(float64); ok {
  100. env["currentTimestamp"] = strconv.Itoa(int(n))
  101. } else {
  102. env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
  103. }
  104. var (
  105. ret []byte
  106. gas *big.Int
  107. err error
  108. logs state.Logs
  109. )
  110. ret, logs, gas, err = RunVm(statedb, env, test.Exec)
  111. rexp := common.FromHex(test.Out)
  112. if bytes.Compare(rexp, ret) != 0 {
  113. t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
  114. }
  115. if len(test.Gas) == 0 && err == nil {
  116. t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
  117. } else {
  118. gexp := common.Big(test.Gas)
  119. if gexp.Cmp(gas) != 0 {
  120. t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
  121. }
  122. }
  123. for addr, account := range test.Post {
  124. obj := statedb.GetStateObject(common.HexToAddress(addr))
  125. if obj == nil {
  126. continue
  127. }
  128. for addr, value := range account.Storage {
  129. v := obj.GetState(common.HexToHash(addr))
  130. vexp := common.HexToHash(value)
  131. if v != vexp {
  132. t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big())
  133. }
  134. }
  135. }
  136. if len(test.Logs) > 0 {
  137. if len(test.Logs) != len(logs) {
  138. t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs))
  139. } else {
  140. for i, log := range test.Logs {
  141. if common.HexToAddress(log.AddressF) != logs[i].Address {
  142. t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address)
  143. }
  144. if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) {
  145. t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data)
  146. }
  147. if len(log.TopicsF) != len(logs[i].Topics) {
  148. t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics)
  149. } else {
  150. for j, topic := range log.TopicsF {
  151. if common.HexToHash(topic) != logs[i].Topics[j] {
  152. t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j])
  153. }
  154. }
  155. }
  156. genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256)
  157. if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
  158. t.Errorf("'%s' bloom mismatch", name)
  159. }
  160. }
  161. }
  162. }
  163. fmt.Println("VM test passed: ", name)
  164. //fmt.Println(string(statedb.Dump()))
  165. }
  166. // logger.Flush()
  167. }
  168. type Env struct {
  169. depth int
  170. state *state.StateDB
  171. skipTransfer bool
  172. initial bool
  173. Gas *big.Int
  174. origin common.Address
  175. //parent common.Hash
  176. coinbase common.Address
  177. number *big.Int
  178. time int64
  179. difficulty *big.Int
  180. gasLimit *big.Int
  181. logs state.Logs
  182. vmTest bool
  183. }
  184. func NewEnv(state *state.StateDB) *Env {
  185. return &Env{
  186. state: state,
  187. }
  188. }
  189. func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
  190. env := NewEnv(state)
  191. env.origin = common.HexToAddress(exeValues["caller"])
  192. //env.parent = common.Hex2Bytes(envValues["previousHash"])
  193. env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
  194. env.number = common.Big(envValues["currentNumber"])
  195. env.time = common.Big(envValues["currentTimestamp"]).Int64()
  196. env.difficulty = common.Big(envValues["currentDifficulty"])
  197. env.gasLimit = common.Big(envValues["currentGasLimit"])
  198. env.Gas = new(big.Int)
  199. return env
  200. }
  201. func (self *Env) Origin() common.Address { return self.origin }
  202. func (self *Env) BlockNumber() *big.Int { return self.number }
  203. //func (self *Env) PrevHash() []byte { return self.parent }
  204. func (self *Env) Coinbase() common.Address { return self.coinbase }
  205. func (self *Env) Time() int64 { return self.time }
  206. func (self *Env) Difficulty() *big.Int { return self.difficulty }
  207. func (self *Env) State() *state.StateDB { return self.state }
  208. func (self *Env) GasLimit() *big.Int { return self.gasLimit }
  209. func (self *Env) VmType() vm.Type { return vm.StdVmTy }
  210. func (self *Env) GetHash(n uint64) common.Hash {
  211. return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
  212. }
  213. func (self *Env) AddLog(log *state.Log) {
  214. self.state.AddLog(log)
  215. }
  216. func (self *Env) Depth() int { return self.depth }
  217. func (self *Env) SetDepth(i int) { self.depth = i }
  218. func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
  219. if self.skipTransfer {
  220. // ugly hack
  221. if self.initial {
  222. self.initial = false
  223. return nil
  224. }
  225. if from.Balance().Cmp(amount) < 0 {
  226. return errors.New("Insufficient balance in account")
  227. }
  228. return nil
  229. }
  230. return vm.Transfer(from, to, amount)
  231. }
  232. func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
  233. exec := core.NewExecution(self, addr, data, gas, price, value)
  234. return exec
  235. }
  236. func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
  237. if self.vmTest && self.depth > 0 {
  238. caller.ReturnGas(gas, price)
  239. return nil, nil
  240. }
  241. exe := self.vm(&addr, data, gas, price, value)
  242. ret, err := exe.Call(addr, caller)
  243. self.Gas = exe.Gas
  244. return ret, err
  245. }
  246. func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
  247. if self.vmTest && self.depth > 0 {
  248. caller.ReturnGas(gas, price)
  249. return nil, nil
  250. }
  251. caddr := caller.Address()
  252. exe := self.vm(&caddr, data, gas, price, value)
  253. return exe.Call(addr, caller)
  254. }
  255. func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
  256. exe := self.vm(nil, data, gas, price, value)
  257. if self.vmTest {
  258. caller.ReturnGas(gas, price)
  259. nonce := self.state.GetNonce(caller.Address())
  260. obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))
  261. return nil, nil, obj
  262. } else {
  263. return exe.Create(caller)
  264. }
  265. }
  266. func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
  267. var (
  268. to = common.HexToAddress(exec["address"])
  269. from = common.HexToAddress(exec["caller"])
  270. data = common.FromHex(exec["data"])
  271. gas = common.Big(exec["gas"])
  272. price = common.Big(exec["gasPrice"])
  273. value = common.Big(exec["value"])
  274. )
  275. // Reset the pre-compiled contracts for VM tests.
  276. vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
  277. caller := state.GetOrNewStateObject(from)
  278. vmenv := NewEnvFromMap(state, env, exec)
  279. vmenv.vmTest = true
  280. vmenv.skipTransfer = true
  281. vmenv.initial = true
  282. ret, err := vmenv.Call(caller, to, data, gas, price, value)
  283. return ret, vmenv.state.Logs(), vmenv.Gas, err
  284. }
  285. type Message struct {
  286. from common.Address
  287. to *common.Address
  288. value, gas, price *big.Int
  289. data []byte
  290. nonce uint64
  291. }
  292. func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
  293. return Message{from, to, value, gas, price, data, nonce}
  294. }
  295. func (self Message) Hash() []byte { return nil }
  296. func (self Message) From() (common.Address, error) { return self.from, nil }
  297. func (self Message) To() *common.Address { return self.to }
  298. func (self Message) GasPrice() *big.Int { return self.price }
  299. func (self Message) Gas() *big.Int { return self.gas }
  300. func (self Message) Value() *big.Int { return self.value }
  301. func (self Message) Nonce() uint64 { return self.nonce }
  302. func (self Message) Data() []byte { return self.data }