diff options
-rw-r--r-- | cmd/ethereum/main.go | 2 | ||||
-rw-r--r-- | cmd/utils/flags.go | 9 | ||||
-rw-r--r-- | core/block_processor.go | 17 | ||||
-rw-r--r-- | core/state_transition.go | 33 | ||||
-rw-r--r-- | miner/worker.go | 8 | ||||
-rw-r--r-- | rpc/api.go | 70 | ||||
-rw-r--r-- | vm/vm.go | 8 | ||||
-rw-r--r-- | xeth/xeth.go | 2 |
8 files changed, 47 insertions, 102 deletions
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index c9f620142..10d9c8fa4 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -201,7 +201,7 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) { if len(split) != 2 { utils.Fatalf("Illegal 'unlock' format (address:password)") } - am := utils.GetAccountManager(ctx) + am := eth.AccountManager() // Attempt to unlock the account err := am.Unlock(ethutil.Hex2Bytes(split[0]), split[1]) if err != nil { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2c7d37942..6372aaa42 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -222,15 +222,10 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database, ethutil.D return core.NewChainManager(blockDb, stateDb, new(event.TypeMux)), blockDb, stateDb } -// Global account manager -var km *accounts.Manager - func GetAccountManager(ctx *cli.Context) *accounts.Manager { dataDir := ctx.GlobalString(DataDirFlag.Name) - if km == nil { - ks := crypto.NewKeyStorePassphrase(path.Join(dataDir, "keys")) - km = accounts.NewManager(ks) - } + ks := crypto.NewKeyStorePassphrase(path.Join(dataDir, "keys")) + km := accounts.NewManager(ks) return km } diff --git a/core/block_processor.go b/core/block_processor.go index ea9d06841..7ac8a1bd2 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -80,7 +80,7 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated cb := statedb.GetStateObject(coinbase.Address()) st := NewStateTransition(NewEnv(statedb, self.bc, tx, block), tx, cb) _, err := st.TransitionState() - if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err)) { + if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) { return nil, nil, err } @@ -120,17 +120,12 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state for _, tx := range txs { receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, block, tx, totalUsedGas, transientProcess) + if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) { + return nil, nil, nil, nil, err + } + if err != nil { - switch { - case IsNonceErr(err): - return nil, nil, nil, nil, err - case state.IsGasLimitErr(err): - return nil, nil, nil, nil, err - default: - statelogger.Infoln(err) - erroneous = append(erroneous, tx) - err = nil - } + statelogger.Infoln("TX err:", err) } receipts = append(receipts, receipt) handled = append(handled, tx) diff --git a/core/state_transition.go b/core/state_transition.go index 9b67de149..b1c66d8c9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -184,6 +184,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { } } if err = self.UseGas(big.NewInt(dgas)); err != nil { + println("2") return nil, InvalidTxError(err) } @@ -200,46 +201,14 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { ref.SetCode(ret) } } - - /* - if vmenv, ok := vmenv.(*VMEnv); ok && tryJit { - statelogger.Infof("CREATE: re-running using JIT (PH=%x)\n", stateCopy.Root()[:4]) - // re-run using the JIT (validation for the JIT) - goodState := vmenv.State().Copy() - vmenv.state = stateCopy - vmenv.SetVmType(vm.JitVmTy) - vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) - statelogger.Infof("DONE PH=%x STD_H=%x JIT_H=%x\n", stateCopy.Root()[:4], goodState.Root()[:4], vmenv.State().Root()[:4]) - self.state.Set(goodState) - } - */ } else { ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) - - /* - if vmenv, ok := vmenv.(*VMEnv); ok && tryJit { - statelogger.Infof("CALL: re-running using JIT (PH=%x)\n", stateCopy.Root()[:4]) - // re-run using the JIT (validation for the JIT) - goodState := vmenv.State().Copy() - vmenv.state = stateCopy - vmenv.SetVmType(vm.JitVmTy) - vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) - statelogger.Infof("DONE PH=%x STD_H=%x JIT_H=%x\n", stateCopy.Root()[:4], goodState.Root()[:4], vmenv.State().Root()[:4]) - self.state.Set(goodState) - } - */ } if err != nil && IsValueTransferErr(err) { return nil, InvalidTxError(err) } - /* - if err != nil { - self.UseGas(self.gas) - } - */ - return } diff --git a/miner/worker.go b/miner/worker.go index 21a0522e8..61091f3c0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -209,6 +209,8 @@ gasLimit: err := self.commitTransaction(tx) switch { case core.IsNonceErr(err): + fallthrough + case core.IsInvalidTxErr(err): // Remove invalid transactions remove = append(remove, tx) case state.IsGasLimitErr(err): @@ -222,7 +224,7 @@ gasLimit: } self.eth.TxPool().RemoveSet(remove) - self.current.coinbase.AddBalance(core.BlockReward) + self.current.state.AddBalance(self.coinbase, core.BlockReward) self.current.state.Update(ethutil.Big0) self.push() @@ -258,9 +260,11 @@ 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)) { + if err != nil && (core.IsNonceErr(err) || state.IsGasLimitErr(err) || core.IsInvalidTxErr(err)) { + self.current.state.Set(snap) return err } diff --git a/rpc/api.go b/rpc/api.go index 337611114..fb974883a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -22,7 +22,7 @@ import ( var ( defaultGasPrice = big.NewInt(10000000000000) - defaultGas = big.NewInt(10000) + defaultGas = big.NewInt(50000) filterTickerTime = 15 * time.Second ) @@ -44,8 +44,6 @@ type EthereumApi struct { register map[string][]*NewTxArgs db ethutil.Database - - // defaultBlockAge int64 } func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { @@ -58,7 +56,6 @@ func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { logs: make(map[int]*logFilter), messages: make(map[int]*whisperFilter), db: db, - // defaultBlockAge: -1, } go api.filterManager.Start() go api.start() @@ -66,36 +63,33 @@ func NewEthereumApi(eth *xeth.XEth, dataDir string) *EthereumApi { return api } -// func (self *EthereumApi) setStateByBlockNumber(num int64) { -// chain := self.xeth().Backend().ChainManager() -// var block *types.Block +func (self *EthereumApi) xethWithStateNum(num int64) *xeth.XEth { + chain := self.xeth().Backend().ChainManager() + var block *types.Block -// if self.defaultBlockAge < 0 { -// num = chain.CurrentBlock().Number().Int64() + num + 1 -// } -// block = chain.GetBlockByNumber(uint64(num)) + if num < 0 { + num = chain.CurrentBlock().Number().Int64() + num + 1 + } + block = chain.GetBlockByNumber(uint64(num)) -// if block != nil { -// self.useState(state.New(block.Root(), self.xeth().Backend().StateDb())) -// } else { -// self.useState(chain.State()) -// } -// } + var st *state.StateDB + if block != nil { + st = state.New(block.Root(), self.xeth().Backend().StateDb()) + } else { + st = chain.State() + } + return self.xeth().WithState(st) +} + +func (self *EthereumApi) getStateWithNum(num int64) *xeth.State { + return self.xethWithStateNum(num).State() +} func (self *EthereumApi) start() { timer := time.NewTicker(filterTickerTime) - // events := self.mux.Subscribe(core.ChainEvent{}) - done: for { select { - // case ev := <-events.Chan(): - // switch ev.(type) { - // case core.ChainEvent: - // if self.defaultBlockAge < 0 { - // self.setStateByBlockNumber(self.defaultBlockAge) - // } - // } case <-timer.C: self.logMut.Lock() self.messagesMut.Lock() @@ -277,7 +271,7 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error) } func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error { - result, err := p.xeth().Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + result, err := p.xethWithStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } @@ -290,7 +284,7 @@ func (p *EthereumApi) GetBalance(args *GetBalanceArgs, reply *interface{}) error if err := args.requirements(); err != nil { return err } - state := p.xeth().State().SafeGet(args.Address) + state := p.getStateWithNum(args.BlockNumber).SafeGet(args.Address) *reply = toHex(state.Balance().Bytes()) return nil } @@ -299,7 +293,7 @@ func (p *EthereumApi) GetStorage(args *GetStorageArgs, reply *interface{}) error if err := args.requirements(); err != nil { return err } - *reply = p.xeth().State().SafeGet(args.Address).Storage() + *reply = p.getStateWithNum(args.BlockNumber).SafeGet(args.Address).Storage() return nil } @@ -307,7 +301,7 @@ func (p *EthereumApi) GetStorageAt(args *GetStorageAtArgs, reply *interface{}) e if err := args.requirements(); err != nil { return err } - state := p.xeth().State().SafeGet(args.Address) + state := p.getStateWithNum(args.BlockNumber).SafeGet(args.Address) value := state.StorageString(args.Key) var hx string @@ -328,7 +322,7 @@ func (p *EthereumApi) GetTxCountAt(args *GetTxCountArgs, reply *interface{}) err if err != nil { return err } - *reply = p.xeth().TxCountAt(args.Address) + *reply = p.xethWithStateNum(args.BlockNumber).TxCountAt(args.Address) return nil } @@ -336,7 +330,7 @@ func (p *EthereumApi) GetData(args *GetDataArgs, reply *interface{}) error { if err := args.requirements(); err != nil { return err } - *reply = p.xeth().CodeAt(args.Address) + *reply = p.xethWithStateNum(args.BlockNumber).CodeAt(args.Address) return nil } @@ -482,28 +476,24 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error case "eth_blockNumber": *reply = toHex(p.xeth().Backend().ChainManager().CurrentBlock().Number().Bytes()) case "eth_getBalance": - // TODO handle BlockNumber args := new(GetBalanceArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetBalance(args, reply) case "eth_getStorage", "eth_storageAt": - // TODO handle BlockNumber args := new(GetStorageArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetStorage(args, reply) case "eth_getStorageAt": - // TODO handle BlockNumber args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } return p.GetStorageAt(args, reply) case "eth_getTransactionCount": - // TODO handle BlockNumber args := new(GetTxCountArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err @@ -554,7 +544,6 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error } *reply = toHex(big.NewInt(v).Bytes()) case "eth_getData": - // TODO handle BlockNumber args := new(GetDataArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err @@ -791,13 +780,6 @@ func (self *EthereumApi) xeth() *xeth.XEth { return self.eth } -func (self *EthereumApi) useState(statedb *state.StateDB) { - self.xethMu.Lock() - defer self.xethMu.Unlock() - - self.eth = self.eth.UseState(statedb) -} - func toFilterOptions(options *FilterOptions) core.FilterOptions { var opts core.FilterOptions @@ -37,7 +37,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I context := NewContext(caller, me, code, gas, price) - vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData) + self.Printf("(%d) (%x) %x (code=%d) gas: %v (d) %x", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData).Endl() if self.Recoverable { // Recover from any require exception @@ -696,7 +696,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I if err != nil { stack.push(ethutil.BigFalse) - vmlogger.Debugln(err) + self.Printf("%v").Endl() } else { stack.push(ethutil.BigTrue) @@ -726,7 +726,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I return context.Return(nil), nil default: - vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) + self.Printf("(pc) %-3v Invalid opcode %x\n", pc, op).Endl() panic(fmt.Errorf("Invalid opcode %x", op)) } @@ -894,7 +894,7 @@ func (self *Vm) Printf(format string, v ...interface{}) VirtualMachine { func (self *Vm) Endl() VirtualMachine { if self.debug { if self.logTy == LogTyPretty { - vmlogger.Debugln(self.logStr) + vmlogger.Infoln(self.logStr) self.logStr = "" } } diff --git a/xeth/xeth.go b/xeth/xeth.go index e73cd70c9..891a1e072 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -98,7 +98,7 @@ func New(eth Backend, frontend Frontend) *XEth { } func (self *XEth) Backend() Backend { return self.eth } -func (self *XEth) UseState(statedb *state.StateDB) *XEth { +func (self *XEth) WithState(statedb *state.StateDB) *XEth { xeth := &XEth{ eth: self.eth, blockProcessor: self.blockProcessor, |