github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/tests/util.go (about) 1 // Copyright 2015 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 "strconv" 24 25 "github.com/ethereumproject/go-ethereum/common" 26 "github.com/ethereumproject/go-ethereum/core" 27 "github.com/ethereumproject/go-ethereum/core/state" 28 "github.com/ethereumproject/go-ethereum/core/types" 29 "github.com/ethereumproject/go-ethereum/core/vm" 30 "github.com/ethereumproject/go-ethereum/crypto" 31 "github.com/ethereumproject/go-ethereum/ethdb" 32 "github.com/ethereumproject/go-ethereum/logger/glog" 33 ) 34 35 func init() { 36 glog.SetV(0) 37 } 38 39 func checkLogs(tlog []Log, logs vm.Logs) error { 40 41 if len(tlog) != len(logs) { 42 return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) 43 } else { 44 for i, log := range tlog { 45 if common.HexToAddress(log.AddressF) != logs[i].Address { 46 return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) 47 } 48 49 if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { 50 return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) 51 } 52 53 if len(log.TopicsF) != len(logs[i].Topics) { 54 return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) 55 } else { 56 for j, topic := range log.TopicsF { 57 if common.HexToHash(topic) != logs[i].Topics[j] { 58 return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) 59 } 60 } 61 } 62 genBloom := common.LeftPadBytes(types.LogsBloom(vm.Logs{logs[i]}).Bytes(), 256) 63 64 if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { 65 return fmt.Errorf("bloom mismatch") 66 } 67 } 68 } 69 return nil 70 } 71 72 type Account struct { 73 Balance string 74 Code string 75 Nonce string 76 Storage map[string]string 77 } 78 79 type Log struct { 80 AddressF string `json:"address"` 81 DataF string `json:"data"` 82 TopicsF []string `json:"topics"` 83 BloomF string `json:"bloom"` 84 } 85 86 func (self Log) Address() []byte { return common.Hex2Bytes(self.AddressF) } 87 func (self Log) Data() []byte { return common.Hex2Bytes(self.DataF) } 88 func (self Log) RlpData() interface{} { return nil } 89 func (self Log) Topics() [][]byte { 90 t := make([][]byte, len(self.TopicsF)) 91 for i, topic := range self.TopicsF { 92 t[i] = common.Hex2Bytes(topic) 93 } 94 return t 95 } 96 97 func makePreState(db ethdb.Database, accounts map[string]Account) *state.StateDB { 98 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 99 for addr, account := range accounts { 100 insertAccount(statedb, addr, account) 101 } 102 return statedb 103 } 104 105 func insertAccount(state *state.StateDB, saddr string, account Account) { 106 if common.IsHex(account.Code) { 107 account.Code = account.Code[2:] 108 } 109 addr := common.HexToAddress(saddr) 110 state.SetCode(addr, common.Hex2Bytes(account.Code)) 111 if i, err := strconv.ParseUint(account.Nonce, 0, 64); err != nil { 112 panic(err) 113 } else { 114 state.SetNonce(addr, i) 115 } 116 if i, ok := new(big.Int).SetString(account.Balance, 0); !ok { 117 panic("malformed account balance") 118 } else { 119 state.SetBalance(addr, i) 120 } 121 for a, v := range account.Storage { 122 state.SetState(addr, common.HexToHash(a), common.HexToHash(v)) 123 } 124 } 125 126 type VmEnv struct { 127 CurrentCoinbase string 128 CurrentDifficulty string 129 CurrentGasLimit string 130 CurrentNumber string 131 CurrentTimestamp interface{} 132 PreviousHash string 133 } 134 135 type VmTest struct { 136 Callcreates interface{} 137 //Env map[string]string 138 Env VmEnv 139 Exec map[string]string 140 Transaction map[string]string 141 Logs []Log 142 Gas string 143 Out string 144 Post map[string]Account 145 Pre map[string]Account 146 PostStateRoot string 147 } 148 149 type RuleSet struct { 150 HomesteadBlock *big.Int 151 HomesteadGasRepriceBlock *big.Int 152 DiehardBlock *big.Int 153 ExplosionBlock *big.Int 154 } 155 156 func (r RuleSet) IsHomestead(n *big.Int) bool { 157 return n.Cmp(r.HomesteadBlock) >= 0 158 } 159 func (r RuleSet) GasTable(num *big.Int) *vm.GasTable { 160 if r.HomesteadGasRepriceBlock == nil || num == nil || num.Cmp(r.HomesteadGasRepriceBlock) < 0 { 161 return &vm.GasTable{ 162 ExtcodeSize: big.NewInt(20), 163 ExtcodeCopy: big.NewInt(20), 164 Balance: big.NewInt(20), 165 SLoad: big.NewInt(50), 166 Calls: big.NewInt(40), 167 Suicide: big.NewInt(0), 168 ExpByte: big.NewInt(10), 169 CreateBySuicide: nil, 170 } 171 } 172 if r.DiehardBlock == nil || num == nil || num.Cmp(r.DiehardBlock) < 0 { 173 return &vm.GasTable{ 174 ExtcodeSize: big.NewInt(700), 175 ExtcodeCopy: big.NewInt(700), 176 Balance: big.NewInt(400), 177 SLoad: big.NewInt(200), 178 Calls: big.NewInt(700), 179 Suicide: big.NewInt(5000), 180 ExpByte: big.NewInt(10), 181 CreateBySuicide: big.NewInt(25000), 182 } 183 } 184 185 return &vm.GasTable{ 186 ExtcodeSize: big.NewInt(700), 187 ExtcodeCopy: big.NewInt(700), 188 Balance: big.NewInt(400), 189 SLoad: big.NewInt(200), 190 Calls: big.NewInt(700), 191 Suicide: big.NewInt(5000), 192 ExpByte: big.NewInt(50), 193 CreateBySuicide: big.NewInt(25000), 194 } 195 } 196 197 type Env struct { 198 ruleSet RuleSet 199 depth int 200 state *state.StateDB 201 skipTransfer bool 202 initial bool 203 Gas *big.Int 204 205 origin common.Address 206 parent common.Hash 207 coinbase common.Address 208 209 number *big.Int 210 time *big.Int 211 difficulty *big.Int 212 gasLimit *big.Int 213 214 vmTest bool 215 216 evm *vm.EVM 217 } 218 219 func NewEnv(ruleSet RuleSet, state *state.StateDB) *Env { 220 env := &Env{ 221 ruleSet: ruleSet, 222 state: state, 223 } 224 return env 225 } 226 227 func NewEnvFromMap(ruleSet RuleSet, state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { 228 env := NewEnv(ruleSet, state) 229 230 env.origin = common.HexToAddress(exeValues["caller"]) 231 env.parent = common.HexToHash(envValues["previousHash"]) 232 env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) 233 env.number, _ = new(big.Int).SetString(envValues["currentNumber"], 0) 234 if env.number == nil { 235 panic("malformed current number") 236 } 237 env.time, _ = new(big.Int).SetString(envValues["currentTimestamp"], 0) 238 if env.time == nil { 239 panic("malformed current timestamp") 240 } 241 env.difficulty, _ = new(big.Int).SetString(envValues["currentDifficulty"], 0) 242 if env.difficulty == nil { 243 panic("malformed current difficulty") 244 } 245 env.gasLimit, _ = new(big.Int).SetString(envValues["currentGasLimit"], 0) 246 if env.gasLimit == nil { 247 panic("malformed current gas limit") 248 } 249 env.Gas = new(big.Int) 250 251 env.evm = vm.New(env) 252 253 return env 254 } 255 256 func (self *Env) RuleSet() vm.RuleSet { return self.ruleSet } 257 func (self *Env) Vm() vm.Vm { return self.evm } 258 func (self *Env) Origin() common.Address { return self.origin } 259 func (self *Env) BlockNumber() *big.Int { return self.number } 260 func (self *Env) Coinbase() common.Address { return self.coinbase } 261 func (self *Env) Time() *big.Int { return self.time } 262 func (self *Env) Difficulty() *big.Int { return self.difficulty } 263 func (self *Env) Db() vm.Database { return self.state } 264 func (self *Env) GasLimit() *big.Int { return self.gasLimit } 265 func (self *Env) VmType() vm.Type { return vm.StdVmTy } 266 func (self *Env) GetHash(n uint64) common.Hash { 267 return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String()))) 268 } 269 func (self *Env) AddLog(log *vm.Log) { 270 self.state.AddLog(*log) 271 } 272 func (self *Env) Depth() int { return self.depth } 273 func (self *Env) SetDepth(i int) { self.depth = i } 274 func (self *Env) CanTransfer(from common.Address, balance *big.Int) bool { 275 if self.skipTransfer { 276 if self.initial { 277 self.initial = false 278 return true 279 } 280 } 281 282 return self.state.GetBalance(from).Cmp(balance) >= 0 283 } 284 func (self *Env) SnapshotDatabase() int { 285 return self.state.Snapshot() 286 } 287 func (self *Env) RevertToSnapshot(snapshot int) { 288 self.state.RevertToSnapshot(snapshot) 289 } 290 291 func (self *Env) Transfer(from, to vm.Account, amount *big.Int) { 292 if self.skipTransfer { 293 return 294 } 295 core.Transfer(from, to, amount) 296 } 297 298 func (self *Env) Call(caller vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { 299 if self.vmTest && self.depth > 0 { 300 caller.ReturnGas(gas, price) 301 302 return nil, nil 303 } 304 ret, err := core.Call(self, caller, addr, data, gas, price, value) 305 self.Gas = gas 306 307 return ret, err 308 309 } 310 func (self *Env) CallCode(caller vm.ContractRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { 311 if self.vmTest && self.depth > 0 { 312 caller.ReturnGas(gas, price) 313 314 return nil, nil 315 } 316 return core.CallCode(self, caller, addr, data, gas, price, value) 317 } 318 319 func (self *Env) DelegateCall(caller vm.ContractRef, addr common.Address, data []byte, gas, price *big.Int) ([]byte, error) { 320 if self.vmTest && self.depth > 0 { 321 caller.ReturnGas(gas, price) 322 323 return nil, nil 324 } 325 return core.DelegateCall(self, caller, addr, data, gas, price) 326 } 327 328 func (self *Env) Create(caller vm.ContractRef, data []byte, gas, price, value *big.Int) ([]byte, common.Address, error) { 329 if self.vmTest { 330 caller.ReturnGas(gas, price) 331 332 nonce := self.state.GetNonce(caller.Address()) 333 obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) 334 335 return nil, obj.Address(), nil 336 } else { 337 return core.Create(self, caller, data, gas, price, value) 338 } 339 } 340 341 type Message struct { 342 from common.Address 343 to *common.Address 344 value, gas, price *big.Int 345 data []byte 346 nonce uint64 347 } 348 349 func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { 350 return Message{from, to, value, gas, price, data, nonce} 351 } 352 353 func (self Message) Hash() []byte { return nil } 354 func (self Message) From() (common.Address, error) { return self.from, nil } 355 func (self Message) FromFrontier() (common.Address, error) { return self.from, nil } 356 func (self Message) To() *common.Address { return self.to } 357 func (self Message) GasPrice() *big.Int { return self.price } 358 func (self Message) Gas() *big.Int { return self.gas } 359 func (self Message) Value() *big.Int { return self.value } 360 func (self Message) Nonce() uint64 { return self.nonce } 361 func (self Message) Data() []byte { return self.data }