github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/tests/util.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package tests 18 19 import ( 20 "bytes" 21 "fmt" 22 "math/big" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core" 26 "github.com/ethereum/go-ethereum/core/state" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/core/vm" 29 "github.com/ethereum/go-ethereum/crypto" 30 ) 31 32 func checkLogs(tlog []Log, logs state.Logs) error { 33 34 if len(tlog) != len(logs) { 35 return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) 36 } else { 37 for i, log := range tlog { 38 if common.HexToAddress(log.AddressF) != logs[i].Address { 39 return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) 40 } 41 42 if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { 43 return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) 44 } 45 46 if len(log.TopicsF) != len(logs[i].Topics) { 47 return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) 48 } else { 49 for j, topic := range log.TopicsF { 50 if common.HexToHash(topic) != logs[i].Topics[j] { 51 return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) 52 } 53 } 54 } 55 genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) 56 57 if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { 58 return fmt.Errorf("bloom mismatch") 59 } 60 } 61 } 62 return nil 63 } 64 65 type Account struct { 66 Balance string 67 Code string 68 Nonce string 69 Storage map[string]string 70 } 71 72 type Log struct { 73 AddressF string `json:"address"` 74 DataF string `json:"data"` 75 TopicsF []string `json:"topics"` 76 BloomF string `json:"bloom"` 77 } 78 79 func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } 80 func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } 81 func (self Log) RlpData() interface{} { return nil } 82 func (self Log) Topics() [][]byte { 83 t := make([][]byte, len(self.TopicsF)) 84 for i, topic := range self.TopicsF { 85 t[i] = common.Hex2Bytes(topic) 86 } 87 return t 88 } 89 90 func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { 91 obj := state.NewStateObject(common.HexToAddress(addr), db) 92 obj.SetBalance(common.Big(account.Balance)) 93 94 if common.IsHex(account.Code) { 95 account.Code = account.Code[2:] 96 } 97 obj.SetCode(common.Hex2Bytes(account.Code)) 98 obj.SetNonce(common.Big(account.Nonce).Uint64()) 99 100 return obj 101 } 102 103 type VmEnv struct { 104 CurrentCoinbase string 105 CurrentDifficulty string 106 CurrentGasLimit string 107 CurrentNumber string 108 CurrentTimestamp interface{} 109 PreviousHash string 110 } 111 112 type VmTest struct { 113 Callcreates interface{} 114 //Env map[string]string 115 Env VmEnv 116 Exec map[string]string 117 Transaction map[string]string 118 Logs []Log 119 Gas string 120 Out string 121 Post map[string]Account 122 Pre map[string]Account 123 PostStateRoot string 124 } 125 126 type Env struct { 127 depth int 128 state *state.StateDB 129 skipTransfer bool 130 initial bool 131 Gas *big.Int 132 133 origin common.Address 134 //parent common.Hash 135 coinbase common.Address 136 137 number *big.Int 138 time *big.Int 139 difficulty *big.Int 140 gasLimit *big.Int 141 142 logs []vm.StructLog 143 144 vmTest bool 145 } 146 147 func NewEnv(state *state.StateDB) *Env { 148 return &Env{ 149 state: state, 150 } 151 } 152 153 func (self *Env) StructLogs() []vm.StructLog { 154 return self.logs 155 } 156 157 func (self *Env) AddStructLog(log vm.StructLog) { 158 self.logs = append(self.logs, log) 159 } 160 161 func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { 162 env := NewEnv(state) 163 164 env.origin = common.HexToAddress(exeValues["caller"]) 165 //env.parent = common.Hex2Bytes(envValues["previousHash"]) 166 env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) 167 env.number = common.Big(envValues["currentNumber"]) 168 env.time = common.Big(envValues["currentTimestamp"]) 169 env.difficulty = common.Big(envValues["currentDifficulty"]) 170 env.gasLimit = common.Big(envValues["currentGasLimit"]) 171 env.Gas = new(big.Int) 172 173 return env 174 } 175 176 func (self *Env) Origin() common.Address { return self.origin } 177 func (self *Env) BlockNumber() *big.Int { return self.number } 178 179 //func (self *Env) PrevHash() []byte { return self.parent } 180 func (self *Env) Coinbase() common.Address { return self.coinbase } 181 func (self *Env) Time() *big.Int { return self.time } 182 func (self *Env) Difficulty() *big.Int { return self.difficulty } 183 func (self *Env) State() *state.StateDB { return self.state } 184 func (self *Env) GasLimit() *big.Int { return self.gasLimit } 185 func (self *Env) VmType() vm.Type { return vm.StdVmTy } 186 func (self *Env) GetHash(n uint64) common.Hash { 187 return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) 188 } 189 func (self *Env) AddLog(log *state.Log) { 190 self.state.AddLog(log) 191 } 192 func (self *Env) Depth() int { return self.depth } 193 func (self *Env) SetDepth(i int) { self.depth = i } 194 func (self *Env) CanTransfer(from vm.Account, balance *big.Int) bool { 195 if self.skipTransfer { 196 if self.initial { 197 self.initial = false 198 return true 199 } 200 } 201 202 return from.Balance().Cmp(balance) >= 0 203 } 204 205 func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { 206 if self.skipTransfer { 207 return nil 208 } 209 return vm.Transfer(from, to, amount) 210 } 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 215 return exec 216 } 217 218 func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { 219 if self.vmTest && self.depth > 0 { 220 caller.ReturnGas(gas, price) 221 222 return nil, nil 223 } 224 exe := self.vm(&addr, data, gas, price, value) 225 ret, err := exe.Call(addr, caller) 226 self.Gas = exe.Gas 227 228 return ret, err 229 230 } 231 func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { 232 if self.vmTest && self.depth > 0 { 233 caller.ReturnGas(gas, price) 234 235 return nil, nil 236 } 237 238 caddr := caller.Address() 239 exe := self.vm(&caddr, data, gas, price, value) 240 return exe.Call(addr, caller) 241 } 242 243 func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { 244 exe := self.vm(nil, data, gas, price, value) 245 if self.vmTest { 246 caller.ReturnGas(gas, price) 247 248 nonce := self.state.GetNonce(caller.Address()) 249 obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) 250 251 return nil, nil, obj 252 } else { 253 return exe.Create(caller) 254 } 255 } 256 257 type Message struct { 258 from common.Address 259 to *common.Address 260 value, gas, price *big.Int 261 data []byte 262 nonce uint64 263 } 264 265 func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { 266 return Message{from, to, value, gas, price, data, nonce} 267 } 268 269 func (self Message) Hash() []byte { return nil } 270 func (self Message) From() (common.Address, error) { return self.from, nil } 271 func (self Message) To() *common.Address { return self.to } 272 func (self Message) GasPrice() *big.Int { return self.price } 273 func (self Message) Gas() *big.Int { return self.gas } 274 func (self Message) Value() *big.Int { return self.value } 275 func (self Message) Nonce() uint64 { return self.nonce } 276 func (self Message) Data() []byte { return self.data }