Gas corrections and vm fixes
This commit is contained in:
parent
5ad473d758
commit
198cc69357
@ -115,7 +115,7 @@ done:
|
|||||||
|
|
||||||
cb := state.GetStateObject(coinbase.Address())
|
cb := state.GetStateObject(coinbase.Address())
|
||||||
st := NewStateTransition(cb, tx, state, block)
|
st := NewStateTransition(cb, tx, state, block)
|
||||||
err = st.TransitionState()
|
_, err = st.TransitionState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch {
|
switch {
|
||||||
case IsNonceErr(err):
|
case IsNonceErr(err):
|
||||||
|
@ -31,6 +31,7 @@ type StateTransition struct {
|
|||||||
coinbase, receiver []byte
|
coinbase, receiver []byte
|
||||||
msg Message
|
msg Message
|
||||||
gas, gasPrice *big.Int
|
gas, gasPrice *big.Int
|
||||||
|
initialGas *big.Int
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
@ -47,7 +48,6 @@ type Message interface {
|
|||||||
From() []byte
|
From() []byte
|
||||||
To() []byte
|
To() []byte
|
||||||
|
|
||||||
GasValue() *big.Int
|
|
||||||
GasPrice() *big.Int
|
GasPrice() *big.Int
|
||||||
Gas() *big.Int
|
Gas() *big.Int
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
@ -65,8 +65,12 @@ func MessageCreatesContract(msg Message) bool {
|
|||||||
return len(msg.To()) == 0
|
return len(msg.To()) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MessageGasValue(msg Message) *big.Int {
|
||||||
|
return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
|
||||||
|
}
|
||||||
|
|
||||||
func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
|
func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
|
||||||
return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
|
return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) VmEnv() vm.Environment {
|
func (self *StateTransition) VmEnv() vm.Environment {
|
||||||
@ -78,33 +82,16 @@ func (self *StateTransition) VmEnv() vm.Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) Coinbase() *state.StateObject {
|
func (self *StateTransition) Coinbase() *state.StateObject {
|
||||||
if self.cb != nil {
|
return self.state.GetOrNewStateObject(self.coinbase)
|
||||||
return self.cb
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cb = self.state.GetOrNewStateObject(self.coinbase)
|
|
||||||
return self.cb
|
|
||||||
}
|
}
|
||||||
func (self *StateTransition) From() *state.StateObject {
|
func (self *StateTransition) From() *state.StateObject {
|
||||||
if self.sen != nil {
|
return self.state.GetOrNewStateObject(self.msg.From())
|
||||||
return self.sen
|
|
||||||
}
|
|
||||||
|
|
||||||
self.sen = self.state.GetOrNewStateObject(self.msg.From())
|
|
||||||
|
|
||||||
return self.sen
|
|
||||||
}
|
}
|
||||||
func (self *StateTransition) To() *state.StateObject {
|
func (self *StateTransition) To() *state.StateObject {
|
||||||
if self.msg != nil && MessageCreatesContract(self.msg) {
|
if self.msg != nil && MessageCreatesContract(self.msg) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return self.state.GetOrNewStateObject(self.msg.To())
|
||||||
if self.rec != nil {
|
|
||||||
return self.rec
|
|
||||||
}
|
|
||||||
|
|
||||||
self.rec = self.state.GetOrNewStateObject(self.msg.To())
|
|
||||||
return self.rec
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) UseGas(amount *big.Int) error {
|
func (self *StateTransition) UseGas(amount *big.Int) error {
|
||||||
@ -124,8 +111,8 @@ func (self *StateTransition) BuyGas() error {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
sender := self.From()
|
sender := self.From()
|
||||||
if sender.Balance().Cmp(self.msg.GasValue()) < 0 {
|
if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 {
|
||||||
return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.msg.GasValue(), sender.Balance())
|
return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance())
|
||||||
}
|
}
|
||||||
|
|
||||||
coinbase := self.Coinbase()
|
coinbase := self.Coinbase()
|
||||||
@ -135,20 +122,12 @@ func (self *StateTransition) BuyGas() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.AddGas(self.msg.Gas())
|
self.AddGas(self.msg.Gas())
|
||||||
sender.SubAmount(self.msg.GasValue())
|
self.initialGas.Set(self.msg.Gas())
|
||||||
|
sender.SubAmount(MessageGasValue(self.msg))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) RefundGas() {
|
|
||||||
coinbase, sender := self.Coinbase(), self.From()
|
|
||||||
coinbase.RefundGas(self.gas, self.msg.GasPrice())
|
|
||||||
|
|
||||||
// Return remaining gas
|
|
||||||
remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
|
|
||||||
sender.AddAmount(remaining)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StateTransition) preCheck() (err error) {
|
func (self *StateTransition) preCheck() (err error) {
|
||||||
var (
|
var (
|
||||||
msg = self.msg
|
msg = self.msg
|
||||||
@ -168,7 +147,7 @@ func (self *StateTransition) preCheck() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) TransitionState() (err error) {
|
func (self *StateTransition) TransitionState() (ret []byte, err error) {
|
||||||
statelogger.Debugf("(~) %x\n", self.msg.Hash())
|
statelogger.Debugf("(~) %x\n", self.msg.Hash())
|
||||||
|
|
||||||
// XXX Transactions after this point are considered valid.
|
// XXX Transactions after this point are considered valid.
|
||||||
@ -204,7 +183,6 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret []byte
|
|
||||||
vmenv := self.VmEnv()
|
vmenv := self.VmEnv()
|
||||||
var ref vm.ClosureRef
|
var ref vm.ClosureRef
|
||||||
if MessageCreatesContract(msg) {
|
if MessageCreatesContract(msg) {
|
||||||
@ -231,3 +209,26 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
|
|||||||
|
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StateTransition) RefundGas() {
|
||||||
|
coinbaseSub := new(big.Int).Set(self.gas)
|
||||||
|
uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
|
||||||
|
for addr, refs := range self.state.Refunds() {
|
||||||
|
for _, ref := range refs {
|
||||||
|
coinbaseSub.Add(self.gas, ref)
|
||||||
|
refund := ethutil.BigMin(uhalf, ref)
|
||||||
|
self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coinbase, sender := self.Coinbase(), self.From()
|
||||||
|
coinbase.RefundGas(coinbaseSub, self.msg.GasPrice())
|
||||||
|
|
||||||
|
// Return remaining gas
|
||||||
|
remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
|
||||||
|
sender.AddAmount(remaining)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StateTransition) GasUsed() *big.Int {
|
||||||
|
return new(big.Int).Sub(self.initialGas, self.gas)
|
||||||
|
}
|
||||||
|
@ -46,15 +46,6 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
|
|||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) GasValue() *big.Int {
|
|
||||||
return new(big.Int).Mul(self.gas, self.gasPrice)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Transaction) TotalValue() *big.Int {
|
|
||||||
v := self.GasValue()
|
|
||||||
return v.Add(v, self.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Transaction) Hash() []byte {
|
func (tx *Transaction) Hash() []byte {
|
||||||
data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
|
data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ type StateDB struct {
|
|||||||
|
|
||||||
manifest *Manifest
|
manifest *Manifest
|
||||||
|
|
||||||
refund map[string][]refund
|
refund map[string][]*big.Int
|
||||||
|
|
||||||
logs Logs
|
logs Logs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new state from a given trie
|
// Create a new state from a given trie
|
||||||
func New(trie *trie.Trie) *StateDB {
|
func New(trie *trie.Trie) *StateDB {
|
||||||
return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]refund)}
|
return &StateDB{Trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string][]*big.Int)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) EmptyLogs() {
|
func (self *StateDB) EmptyLogs() {
|
||||||
@ -55,12 +55,8 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int {
|
|||||||
return ethutil.Big0
|
return ethutil.Big0
|
||||||
}
|
}
|
||||||
|
|
||||||
type refund struct {
|
func (self *StateDB) Refund(addr []byte, gas *big.Int) {
|
||||||
gas, price *big.Int
|
self.refund[string(addr)] = append(self.refund[string(addr)], gas)
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StateDB) Refund(addr []byte, gas, price *big.Int) {
|
|
||||||
self.refund[string(addr)] = append(self.refund[string(addr)], refund{gas, price})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
|
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
|
||||||
@ -273,23 +269,17 @@ func (s *StateDB) Sync() {
|
|||||||
|
|
||||||
func (self *StateDB) Empty() {
|
func (self *StateDB) Empty() {
|
||||||
self.stateObjects = make(map[string]*StateObject)
|
self.stateObjects = make(map[string]*StateObject)
|
||||||
self.refund = make(map[string][]refund)
|
self.refund = make(map[string][]*big.Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StateDB) Refunds() map[string][]*big.Int {
|
||||||
|
return self.refund
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Update(gasUsed *big.Int) {
|
func (self *StateDB) Update(gasUsed *big.Int) {
|
||||||
var deleted bool
|
var deleted bool
|
||||||
|
|
||||||
// Refund any gas that's left
|
self.refund = make(map[string][]*big.Int)
|
||||||
// XXX THIS WILL CHANGE IN POC8
|
|
||||||
uhalf := new(big.Int).Div(gasUsed, ethutil.Big2)
|
|
||||||
for addr, refs := range self.refund {
|
|
||||||
for _, ref := range refs {
|
|
||||||
refund := ethutil.BigMin(uhalf, ref.gas)
|
|
||||||
|
|
||||||
self.GetStateObject([]byte(addr)).AddBalance(refund.Mul(refund, ref.price))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.refund = make(map[string][]refund)
|
|
||||||
|
|
||||||
for _, stateObject := range self.stateObjects {
|
for _, stateObject := range self.stateObjects {
|
||||||
if stateObject.remove {
|
if stateObject.remove {
|
||||||
|
@ -44,6 +44,7 @@ func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues
|
|||||||
env.time = ethutil.Big(envValues["currentTimestamp"]).Int64()
|
env.time = ethutil.Big(envValues["currentTimestamp"]).Int64()
|
||||||
env.difficulty = ethutil.Big(envValues["currentDifficulty"])
|
env.difficulty = ethutil.Big(envValues["currentDifficulty"])
|
||||||
env.gasLimit = ethutil.Big(envValues["currentGasLimit"])
|
env.gasLimit = ethutil.Big(envValues["currentGasLimit"])
|
||||||
|
env.Gas = new(big.Int)
|
||||||
|
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
@ -110,7 +111,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log
|
|||||||
return ret, vmenv.logs, vmenv.Gas, err
|
return ret, vmenv.logs, vmenv.Gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunState(state *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
|
func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
|
||||||
var (
|
var (
|
||||||
keyPair, _ = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(tx["secretKey"])))
|
keyPair, _ = crypto.NewKeyPairFromSec([]byte(ethutil.Hex2Bytes(tx["secretKey"])))
|
||||||
to = FromHex(tx["to"])
|
to = FromHex(tx["to"])
|
||||||
@ -118,13 +119,39 @@ func RunState(state *state.StateDB, env, tx map[string]string) ([]byte, state.Lo
|
|||||||
gas = ethutil.Big(tx["gasLimit"])
|
gas = ethutil.Big(tx["gasLimit"])
|
||||||
price = ethutil.Big(tx["gasPrice"])
|
price = ethutil.Big(tx["gasPrice"])
|
||||||
value = ethutil.Big(tx["value"])
|
value = ethutil.Big(tx["value"])
|
||||||
|
caddr = FromHex(env["currentCoinbase"])
|
||||||
)
|
)
|
||||||
|
|
||||||
caller := state.GetOrNewStateObject(keyPair.Address())
|
coinbase := statedb.GetOrNewStateObject(caddr)
|
||||||
|
coinbase.SetGasPool(ethutil.Big(env["currentGasLimit"]))
|
||||||
|
|
||||||
vmenv := NewEnvFromMap(state, env, tx)
|
message := NewMessage(keyPair.Address(), to, data, value, gas, price)
|
||||||
vmenv.origin = caller.Address()
|
Log.DebugDetailf("message{ to: %x, from %x, value: %v, gas: %v, price: %v }\n", message.to[:4], message.from[:4], message.value, message.gas, message.price)
|
||||||
ret, err := vmenv.Call(caller, to, data, gas, price, value)
|
st := core.NewStateTransition(coinbase, message, statedb, nil)
|
||||||
|
vmenv := NewEnvFromMap(statedb, env, tx)
|
||||||
|
vmenv.origin = keyPair.Address()
|
||||||
|
st.Env = vmenv
|
||||||
|
ret, err := st.TransitionState()
|
||||||
|
statedb.Update(vmenv.Gas)
|
||||||
|
|
||||||
return ret, vmenv.logs, vmenv.Gas, err
|
return ret, vmenv.logs, vmenv.Gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
from, to []byte
|
||||||
|
value, gas, price *big.Int
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessage(from, to, data []byte, value, gas, price *big.Int) Message {
|
||||||
|
return Message{from, to, value, gas, price, data}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Message) Hash() []byte { return nil }
|
||||||
|
func (self Message) From() []byte { return self.from }
|
||||||
|
func (self Message) To() []byte { return self.to }
|
||||||
|
func (self Message) GasPrice() *big.Int { return self.price }
|
||||||
|
func (self Message) Gas() *big.Int { return self.gas }
|
||||||
|
func (self Message) Value() *big.Int { return self.value }
|
||||||
|
func (self Message) Nonce() uint64 { return 0 }
|
||||||
|
func (self Message) Data() []byte { return self.data }
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
"github.com/ethereum/go-ethereum/tests/helper"
|
"github.com/ethereum/go-ethereum/tests/helper"
|
||||||
)
|
)
|
||||||
@ -76,11 +77,18 @@ func RunVmTest(p string, t *testing.T) {
|
|||||||
tests := make(map[string]VmTest)
|
tests := make(map[string]VmTest)
|
||||||
helper.CreateFileTests(t, p, &tests)
|
helper.CreateFileTests(t, p, &tests)
|
||||||
|
|
||||||
|
helper.Logger.SetLogLevel(5)
|
||||||
for name, test := range tests {
|
for name, test := range tests {
|
||||||
|
if name != "ABAcalls1" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
statedb := state.New(helper.NewTrie())
|
statedb := state.New(helper.NewTrie())
|
||||||
for addr, account := range test.Pre {
|
for addr, account := range test.Pre {
|
||||||
obj := StateObjectFromAccount(addr, account)
|
obj := StateObjectFromAccount(addr, account)
|
||||||
statedb.SetStateObject(obj)
|
statedb.SetStateObject(obj)
|
||||||
|
for a, v := range account.Storage {
|
||||||
|
obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Yeah, yeah...
|
// XXX Yeah, yeah...
|
||||||
@ -129,6 +137,16 @@ func RunVmTest(p string, t *testing.T) {
|
|||||||
|
|
||||||
for addr, account := range test.Post {
|
for addr, account := range test.Post {
|
||||||
obj := statedb.GetStateObject(helper.FromHex(addr))
|
obj := statedb.GetStateObject(helper.FromHex(addr))
|
||||||
|
if obj == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(test.Exec) == 0 {
|
||||||
|
if obj.Balance().Cmp(ethutil.Big(account.Balance)) != 0 {
|
||||||
|
t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(ethutil.Big(account.Balance), obj.Balance()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for addr, value := range account.Storage {
|
for addr, value := range account.Storage {
|
||||||
v := obj.GetState(helper.FromHex(addr)).Bytes()
|
v := obj.GetState(helper.FromHex(addr)).Bytes()
|
||||||
vexp := helper.FromHex(value)
|
vexp := helper.FromHex(value)
|
||||||
@ -149,6 +167,7 @@ func RunVmTest(p string, t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
|
// I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
|
||||||
@ -212,7 +231,12 @@ func TestStateRecursiveCreate(t *testing.T) {
|
|||||||
RunVmTest(fn, t)
|
RunVmTest(fn, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateSpecialTest(t *testing.T) {
|
func TestStateSpecial(t *testing.T) {
|
||||||
const fn = "../files/StateTests/stSpecialTest.json"
|
const fn = "../files/StateTests/stSpecialTest.json"
|
||||||
RunVmTest(fn, t)
|
RunVmTest(fn, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStateRefund(t *testing.T) {
|
||||||
|
const fn = "../files/StateTests/stRefundTest.json"
|
||||||
|
RunVmTest(fn, t)
|
||||||
|
}
|
||||||
|
@ -37,7 +37,7 @@ var (
|
|||||||
GasLog = big.NewInt(32)
|
GasLog = big.NewInt(32)
|
||||||
GasSha256 = big.NewInt(50)
|
GasSha256 = big.NewInt(50)
|
||||||
GasRipemd = big.NewInt(50)
|
GasRipemd = big.NewInt(50)
|
||||||
GasEcrecover = big.NewInt(100)
|
GasEcrecover = big.NewInt(500)
|
||||||
|
|
||||||
Pow256 = ethutil.BigPow(2, 256)
|
Pow256 = ethutil.BigPow(2, 256)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
@ -112,7 +113,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
return closure.Return(nil), nil
|
return closure.Return(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.env.Depth(), closure.Address(), closure.Gas, callData)
|
vmlogger.Debugf("(%d) (%x) %x gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), closure.Gas, callData)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
prevStep = step
|
prevStep = step
|
||||||
@ -185,11 +186,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
// 0 => non 0
|
// 0 => non 0
|
||||||
mult = ethutil.Big3
|
mult = ethutil.Big3
|
||||||
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
|
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
|
||||||
statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
|
statedb.Refund(caller.Address(), GasSStoreRefund)
|
||||||
|
|
||||||
mult = ethutil.Big0
|
mult = ethutil.Big0
|
||||||
} else {
|
} else {
|
||||||
// non 0 => non 0
|
// non 0 => non 0 (or 0 => 0)
|
||||||
mult = ethutil.Big1
|
mult = ethutil.Big1
|
||||||
}
|
}
|
||||||
gas.Set(new(big.Int).Mul(mult, GasSStore))
|
gas.Set(new(big.Int).Mul(mult, GasSStore))
|
||||||
@ -660,7 +661,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
cOff = 0
|
cOff = 0
|
||||||
l = 0
|
l = 0
|
||||||
} else if cOff+l > size {
|
} else if cOff+l > size {
|
||||||
l = 0
|
l = uint64(math.Min(float64(cOff+l), float64(size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
codeCopy := code[cOff : cOff+l]
|
codeCopy := code[cOff : cOff+l]
|
||||||
@ -776,10 +777,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
statedb.SetState(closure.Address(), loc.Bytes(), val)
|
statedb.SetState(closure.Address(), loc.Bytes(), val)
|
||||||
|
|
||||||
// Debug sessions are allowed to run without message
|
|
||||||
if closure.message != nil {
|
|
||||||
closure.message.AddStorageChange(loc.Bytes())
|
closure.message.AddStorageChange(loc.Bytes())
|
||||||
}
|
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case JUMP:
|
case JUMP:
|
||||||
@ -898,10 +896,12 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
|
|||||||
|
|
||||||
return closure.Return(ret), nil
|
return closure.Return(ret), nil
|
||||||
case SUICIDE:
|
case SUICIDE:
|
||||||
|
|
||||||
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
||||||
|
balance := statedb.GetBalance(closure.Address())
|
||||||
|
|
||||||
receiver.AddAmount(statedb.GetBalance(closure.Address()))
|
self.Printf(" => (%x) %v", receiver.Address()[:4], balance)
|
||||||
|
|
||||||
|
receiver.AddAmount(balance)
|
||||||
statedb.Delete(closure.Address())
|
statedb.Delete(closure.Address())
|
||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
|
Loading…
Reference in New Issue
Block a user