vm_test_util.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. // Compare expectedand actual return
  112. rexp := common.FromHex(test.Out)
  113. if bytes.Compare(rexp, ret) != 0 {
  114. t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
  115. }
  116. // Check gas usage
  117. if len(test.Gas) == 0 && err == nil {
  118. t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
  119. } else {
  120. gexp := common.Big(test.Gas)
  121. if gexp.Cmp(gas) != 0 {
  122. t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
  123. }
  124. }
  125. // check post state
  126. for addr, account := range test.Post {
  127. obj := statedb.GetStateObject(common.HexToAddress(addr))
  128. if obj == nil {
  129. continue
  130. }
  131. for addr, value := range account.Storage {
  132. v := obj.GetState(common.HexToHash(addr))
  133. vexp := common.HexToHash(value)
  134. if v != vexp {
  135. 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())
  136. }
  137. }
  138. }
  139. // check logs
  140. if len(test.Logs) > 0 {
  141. CheckLogs(test.Logs, logs, t)
  142. }
  143. fmt.Println("VM test passed: ", name)
  144. //fmt.Println(string(statedb.Dump()))
  145. }
  146. // logger.Flush()
  147. }
  148. type Env struct {
  149. depth int
  150. state *state.StateDB
  151. skipTransfer bool
  152. initial bool
  153. Gas *big.Int
  154. origin common.Address
  155. //parent common.Hash
  156. coinbase common.Address
  157. number *big.Int
  158. time int64
  159. difficulty *big.Int
  160. gasLimit *big.Int
  161. logs state.Logs
  162. vmTest bool
  163. }
  164. func NewEnv(state *state.StateDB) *Env {
  165. return &Env{
  166. state: state,
  167. }
  168. }
  169. func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
  170. env := NewEnv(state)
  171. env.origin = common.HexToAddress(exeValues["caller"])
  172. //env.parent = common.Hex2Bytes(envValues["previousHash"])
  173. env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
  174. env.number = common.Big(envValues["currentNumber"])
  175. env.time = common.Big(envValues["currentTimestamp"]).Int64()
  176. env.difficulty = common.Big(envValues["currentDifficulty"])
  177. env.gasLimit = common.Big(envValues["currentGasLimit"])
  178. env.Gas = new(big.Int)
  179. return env
  180. }
  181. func (self *Env) Origin() common.Address { return self.origin }
  182. func (self *Env) BlockNumber() *big.Int { return self.number }
  183. //func (self *Env) PrevHash() []byte { return self.parent }
  184. func (self *Env) Coinbase() common.Address { return self.coinbase }
  185. func (self *Env) Time() int64 { return self.time }
  186. func (self *Env) Difficulty() *big.Int { return self.difficulty }
  187. func (self *Env) State() *state.StateDB { return self.state }
  188. func (self *Env) GasLimit() *big.Int { return self.gasLimit }
  189. func (self *Env) VmType() vm.Type { return vm.StdVmTy }
  190. func (self *Env) GetHash(n uint64) common.Hash {
  191. return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
  192. }
  193. func (self *Env) AddLog(log *state.Log) {
  194. self.state.AddLog(log)
  195. }
  196. func (self *Env) Depth() int { return self.depth }
  197. func (self *Env) SetDepth(i int) { self.depth = i }
  198. func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
  199. if self.skipTransfer {
  200. // ugly hack
  201. if self.initial {
  202. self.initial = false
  203. return nil
  204. }
  205. if from.Balance().Cmp(amount) < 0 {
  206. return errors.New("Insufficient balance in account")
  207. }
  208. return nil
  209. }
  210. return vm.Transfer(from, to, amount)
  211. }
  212. func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
  213. exec := core.NewExecution(self, addr, data, gas, price, value)
  214. return exec
  215. }
  216. func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
  217. if self.vmTest && self.depth > 0 {
  218. caller.ReturnGas(gas, price)
  219. return nil, nil
  220. }
  221. exe := self.vm(&addr, data, gas, price, value)
  222. ret, err := exe.Call(addr, caller)
  223. self.Gas = exe.Gas
  224. return ret, err
  225. }
  226. func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
  227. if self.vmTest && self.depth > 0 {
  228. caller.ReturnGas(gas, price)
  229. return nil, nil
  230. }
  231. caddr := caller.Address()
  232. exe := self.vm(&caddr, data, gas, price, value)
  233. return exe.Call(addr, caller)
  234. }
  235. func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
  236. exe := self.vm(nil, data, gas, price, value)
  237. if self.vmTest {
  238. caller.ReturnGas(gas, price)
  239. nonce := self.state.GetNonce(caller.Address())
  240. obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))
  241. return nil, nil, obj
  242. } else {
  243. return exe.Create(caller)
  244. }
  245. }
  246. func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
  247. var (
  248. to = common.HexToAddress(exec["address"])
  249. from = common.HexToAddress(exec["caller"])
  250. data = common.FromHex(exec["data"])
  251. gas = common.Big(exec["gas"])
  252. price = common.Big(exec["gasPrice"])
  253. value = common.Big(exec["value"])
  254. )
  255. // Reset the pre-compiled contracts for VM tests.
  256. vm.Precompiled = make(map[string]*vm.PrecompiledAccount)
  257. caller := state.GetOrNewStateObject(from)
  258. vmenv := NewEnvFromMap(state, env, exec)
  259. vmenv.vmTest = true
  260. vmenv.skipTransfer = true
  261. vmenv.initial = true
  262. ret, err := vmenv.Call(caller, to, data, gas, price, value)
  263. return ret, vmenv.state.Logs(), vmenv.Gas, err
  264. }
  265. type Message struct {
  266. from common.Address
  267. to *common.Address
  268. value, gas, price *big.Int
  269. data []byte
  270. nonce uint64
  271. }
  272. func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
  273. return Message{from, to, value, gas, price, data, nonce}
  274. }
  275. func (self Message) Hash() []byte { return nil }
  276. func (self Message) From() (common.Address, error) { return self.from, nil }
  277. func (self Message) To() *common.Address { return self.to }
  278. func (self Message) GasPrice() *big.Int { return self.price }
  279. func (self Message) Gas() *big.Int { return self.gas }
  280. func (self Message) Value() *big.Int { return self.value }
  281. func (self Message) Nonce() uint64 { return self.nonce }
  282. func (self Message) Data() []byte { return self.data }