github.com/Gessiux/neatchain@v1.3.1/chain/core/state_transition1.go (about) 1 package core 2 3 import ( 4 "math/big" 5 6 "github.com/Gessiux/neatchain/chain/core/vm" 7 "github.com/Gessiux/neatchain/chain/log" 8 ) 9 10 // ApplyMessage computes the new state by applying the given message 11 // against the old state within the environment. 12 // 13 // ApplyMessage returns the bytes returned by any EVM execution (if it took place), 14 // the gas used (which includes gas refunds) and an error if it failed. An error always 15 // indicates a core error meaning that the message would always fail for that particular 16 // state and would never be accepted within a block. 17 func ApplyMessageEx(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, *big.Int, bool, error) { 18 return NewStateTransition(evm, msg, gp).TransitionDbEx() 19 } 20 21 // TransitionDbEx will move the state by applying the message against the given environment. 22 func (st *StateTransition) TransitionDbEx() (ret []byte, usedGas uint64, usedMoney *big.Int, failed bool, err error) { 23 24 if err = st.preCheck(); err != nil { 25 return 26 } 27 msg := st.msg 28 sender := st.from() // err checked in preCheck 29 30 homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber) 31 contractCreation := msg.To() == nil 32 33 // Pay intrinsic gas 34 gas, err := IntrinsicGas(st.data, contractCreation, homestead) 35 if err != nil { 36 return nil, 0, nil, false, err 37 } 38 if err = st.useGas(gas); err != nil { 39 return nil, 0, nil, false, err 40 } 41 42 var ( 43 evm = st.evm 44 // vm errors do not effect consensus and are therefor 45 // not assigned to err, except for insufficient balance 46 // error. 47 vmerr error 48 ) 49 50 //log.Debugf("TransitionDbEx 0\n") 51 52 if contractCreation { 53 ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value) 54 } else { 55 // Increment the nonce for the next transaction 56 //log.Debugf("TransitionDbEx 1, sender is %x, nonce is \n", sender.Address(), st.state.GetNonce(sender.Address())+1) 57 58 st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1) 59 ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value) 60 61 //log.Debugf("TransitionDbEx 2\n") 62 63 } 64 65 //log.Debugf("TransitionDbEx 3\n") 66 67 if vmerr != nil { 68 log.Debug("VM returned with error", "err", vmerr) 69 // The only possible consensus-error would be if there wasn't 70 // sufficient balance to make the transfer happen. The first 71 // balance transfer may never fail. 72 if vmerr == vm.ErrInsufficientBalance { 73 return nil, 0, nil, false, vmerr 74 } 75 } 76 77 st.refundGas() 78 79 //log.Debugf("TransitionDbEx 4, coinbase is %x, balance is %v\n", 80 // st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) 81 82 //st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) 83 usedMoney = new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice) 84 85 //log.Debugf("TransitionDbEx 5\n") 86 87 //log.Debugf("TransitionDbEx, send.balance is %v\n", st.state.GetBalance(sender.Address())) 88 //log.Debugf("TransitionDbEx, return ret-%v, st.gasUsed()-%v, usedMoney-%v, vmerr-%v, err-%v\n", 89 // ret, st.gasUsed(), usedMoney, vmerr, err) 90 91 return ret, st.gasUsed(), usedMoney, vmerr != nil, err 92 }