Bladeren bron

Removed some of that gas pre pay magic

obscuren 10 jaren geleden
bovenliggende
commit
310ca62285
6 gewijzigde bestanden met toevoegingen van 53 en 56 verwijderingen
  1. 8 9
      core/block_processor.go
  2. 25 22
      core/state_transition.go
  3. 0 1
      miner/worker.go
  4. 18 15
      state/state_object.go
  5. 1 2
      tests/helper/vm.go
  6. 1 7
      vm/vm.go

+ 8 - 9
core/block_processor.go

@@ -78,21 +78,20 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
 	// If we are mining this block and validating we want to set the logs back to 0
 	statedb.EmptyLogs()
 
-	txGas := new(big.Int).Set(tx.Gas())
-
 	cb := statedb.GetStateObject(coinbase.Address())
-	st := NewStateTransition(NewEnv(statedb, self.bc, tx, block), tx, cb)
-	_, err := st.TransitionState()
+	/*
+		st := NewStateTransition(NewEnv(statedb, self.bc, tx, block), tx, cb)
+		_, err := st.TransitionState()
+	*/
+	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, block), tx, cb)
 	if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
 		return nil, nil, err
 	}
 
-	txGas.Sub(txGas, st.gas)
-
 	// Update the state with pending changes
-	statedb.Update(txGas)
+	statedb.Update(nil)
 
-	cumulative := new(big.Int).Set(usedGas.Add(usedGas, txGas))
+	cumulative := new(big.Int).Set(usedGas.Add(usedGas, gas))
 	receipt := types.NewReceipt(statedb.Root(), cumulative)
 	receipt.SetLogs(statedb.Logs())
 	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
@@ -105,7 +104,7 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
 		go self.eventMux.Post(logs)
 	}
 
-	return receipt, txGas, err
+	return receipt, gas, err
 }
 func (self *BlockProcessor) ChainManager() *ChainManager {
 	return self.bc

+ 25 - 22
core/state_transition.go

@@ -69,6 +69,10 @@ func MessageGasValue(msg Message) *big.Int {
 	return new(big.Int).Mul(msg.Gas(), msg.GasPrice())
 }
 
+func ApplyMessage(env vm.Environment, msg Message, coinbase *state.StateObject) ([]byte, *big.Int, error) {
+	return NewStateTransition(env, msg, coinbase).transitionState()
+}
+
 func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
 	return &StateTransition{
 		coinbase:   coinbase.Address(),
@@ -150,7 +154,7 @@ func (self *StateTransition) preCheck() (err error) {
 	return nil
 }
 
-func (self *StateTransition) TransitionState() (ret []byte, err error) {
+func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, err error) {
 	// statelogger.Debugf("(~) %x\n", self.msg.Hash())
 
 	// XXX Transactions after this point are considered valid.
@@ -163,11 +167,9 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 		sender = self.From()
 	)
 
-	defer self.RefundGas()
-
 	// Transaction gas
 	if err = self.UseGas(vm.GasTx); err != nil {
-		return nil, InvalidTxError(err)
+		return nil, nil, InvalidTxError(err)
 	}
 
 	// Increment the nonce for the next transaction
@@ -184,15 +186,13 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 		}
 	}
 	if err = self.UseGas(big.NewInt(dgas)); err != nil {
-		println("2")
-		return nil, InvalidTxError(err)
+		return nil, nil, InvalidTxError(err)
 	}
 
-	//stateCopy := self.env.State().Copy()
 	vmenv := self.env
 	var ref vm.ContextRef
 	if MessageCreatesContract(msg) {
-		contract := MakeContract(msg, self.state)
+		contract := makeContract(msg, self.state)
 		ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
 		if err == nil {
 			dataGas := big.NewInt(int64(len(ret)))
@@ -208,29 +208,22 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 	}
 
 	if err != nil && IsValueTransferErr(err) {
-		return nil, InvalidTxError(err)
+		return nil, nil, InvalidTxError(err)
 	}
 
-	return
-}
-
-// Converts an transaction in to a state object
-func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
-	addr := AddressFromMessage(msg)
-
-	contract := state.GetOrNewStateObject(addr)
-	contract.SetInitCode(msg.Data())
+	self.refundGas()
+	self.state.AddBalance(self.coinbase, new(big.Int).Mul(self.gasUsed(), self.gasPrice))
 
-	return contract
+	return ret, self.gasUsed(), err
 }
 
-func (self *StateTransition) RefundGas() {
+func (self *StateTransition) refundGas() {
 	coinbase, sender := self.Coinbase(), self.From()
 	// Return remaining gas
 	remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
 	sender.AddBalance(remaining)
 
-	uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2)
+	uhalf := new(big.Int).Div(self.gasUsed(), ethutil.Big2)
 	for addr, ref := range self.state.Refunds() {
 		refund := ethutil.BigMin(uhalf, ref)
 		self.gas.Add(self.gas, refund)
@@ -240,6 +233,16 @@ func (self *StateTransition) RefundGas() {
 	coinbase.RefundGas(self.gas, self.msg.GasPrice())
 }
 
-func (self *StateTransition) GasUsed() *big.Int {
+func (self *StateTransition) gasUsed() *big.Int {
 	return new(big.Int).Sub(self.initialGas, self.gas)
 }
+
+// Converts an message in to a state object
+func makeContract(msg Message, state *state.StateDB) *state.StateObject {
+	addr := AddressFromMessage(msg)
+
+	contract := state.GetOrNewStateObject(addr)
+	contract.SetInitCode(msg.Data())
+
+	return contract
+}

+ 0 - 1
miner/worker.go

@@ -261,7 +261,6 @@ func (self *worker) commitUncle(uncle *types.Header) error {
 
 func (self *worker) commitTransaction(tx *types.Transaction) error {
 	snap := self.current.state.Copy()
-	//fmt.Printf("proc %x %v\n", tx.Hash()[:3], tx.Nonce())
 	receipt, _, err := self.proc.ApplyTransaction(self.current.coinbase, self.current.state, self.current.block, tx, self.current.totalUsedGas, true)
 	if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err) || core.IsInvalidTxErr(err)) {
 		self.current.state.Set(snap)

+ 18 - 15
state/state_object.go

@@ -38,19 +38,27 @@ func (self Storage) Copy() Storage {
 }
 
 type StateObject struct {
+	// State database for storing state changes
 	db ethutil.Database
-	// Address of the object
+	// The state object
+	State *StateDB
+
+	// Address belonging to this account
 	address []byte
-	// Shared attributes
-	balance  *big.Int
+	// The balance of the account
+	balance *big.Int
+	// The nonce of the account
+	nonce uint64
+	// The code hash if code is present (i.e. a contract)
 	codeHash []byte
-	nonce    uint64
-	// Contract related attributes
-	State    *StateDB
-	code     Code
+	// The code for this account
+	code Code
+	// Temporarily initialisation code
 	initCode Code
-
+	// Cached storage (flushed when updated)
 	storage Storage
+	// Temporary prepaid gas, reward after transition
+	prepaid *big.Int
 
 	// Total gas pool is the total amount of gas currently
 	// left if this object is the coinbase. Gas is directly
@@ -77,6 +85,7 @@ func NewStateObject(addr []byte, db ethutil.Database) *StateObject {
 	object.State = New(nil, db) //New(trie.New(ethutil.Config.Db, ""))
 	object.storage = make(Storage)
 	object.gasPool = new(big.Int)
+	object.prepaid = new(big.Int)
 
 	return object
 }
@@ -103,6 +112,7 @@ func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateOb
 	object.State = New(extobject.Root, db)
 	object.storage = make(map[string]*ethutil.Value)
 	object.gasPool = new(big.Int)
+	object.prepaid = new(big.Int)
 	object.code, _ = db.Get(extobject.CodeHash)
 
 	return object
@@ -230,8 +240,6 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error {
 	rGas := new(big.Int).Set(gas)
 	rGas.Mul(rGas, price)
 
-	self.AddBalance(rGas)
-
 	self.dirty = true
 
 	return nil
@@ -239,11 +247,6 @@ func (self *StateObject) BuyGas(gas, price *big.Int) error {
 
 func (self *StateObject) RefundGas(gas, price *big.Int) {
 	self.gasPool.Add(self.gasPool, gas)
-
-	rGas := new(big.Int).Set(gas)
-	rGas.Mul(rGas, price)
-
-	self.balance.Sub(self.balance, rGas)
 }
 
 func (self *StateObject) Copy() *StateObject {

+ 1 - 2
tests/helper/vm.go

@@ -173,9 +173,8 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.
 
 	message := NewMessage(keyPair.Address(), to, data, value, gas, price)
 	vmenv := NewEnvFromMap(statedb, env, tx)
-	st := core.NewStateTransition(vmenv, message, coinbase)
 	vmenv.origin = keyPair.Address()
-	ret, err := st.TransitionState()
+	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
 	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) {
 		statedb.Set(snapshot)
 	}

+ 1 - 7
vm/vm.go

@@ -392,14 +392,8 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 
 			self.Printf(" => %x", context.Address())
 		case BALANCE:
-
 			addr := stack.pop().Bytes()
-			var balance *big.Int
-			if statedb.GetStateObject(addr) != nil {
-				balance = statedb.GetBalance(addr)
-			} else {
-				balance = base
-			}
+			balance := statedb.GetBalance(addr)
 
 			stack.push(balance)