Removal of manual updating of state objects
* You'll only ever need to update the state by calling Update. Update will take care of the updating of it's child state objects.
This commit is contained in:
		
							parent
							
								
									6656f99c54
								
							
						
					
					
						commit
						53e30f750d
					
				| @ -38,12 +38,16 @@ func (s *State) Reset() { | ||||
| 
 | ||||
| 		stateObject.state.Reset() | ||||
| 	} | ||||
| 
 | ||||
| 	s.Empty() | ||||
| } | ||||
| 
 | ||||
| // Syncs the trie and all siblings
 | ||||
| func (s *State) Sync() { | ||||
| 	// Sync all nested states
 | ||||
| 	for _, stateObject := range s.stateObjects { | ||||
| 		s.UpdateStateObject(stateObject) | ||||
| 
 | ||||
| 		if stateObject.state == nil { | ||||
| 			continue | ||||
| 		} | ||||
| @ -52,6 +56,18 @@ func (s *State) Sync() { | ||||
| 	} | ||||
| 
 | ||||
| 	s.trie.Sync() | ||||
| 
 | ||||
| 	s.Empty() | ||||
| } | ||||
| 
 | ||||
| func (self *State) Empty() { | ||||
| 	self.stateObjects = make(map[string]*StateObject) | ||||
| } | ||||
| 
 | ||||
| func (self *State) Update() { | ||||
| 	for _, stateObject := range self.stateObjects { | ||||
| 		self.UpdateStateObject(stateObject) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Purges the current trie.
 | ||||
| @ -68,6 +84,7 @@ func (self *State) UpdateStateObject(stateObject *StateObject) { | ||||
| 	addr := stateObject.Address() | ||||
| 
 | ||||
| 	if self.stateObjects[string(addr)] == nil { | ||||
| 		panic("?") | ||||
| 		self.stateObjects[string(addr)] = stateObject | ||||
| 	} | ||||
| 
 | ||||
| @ -98,13 +115,19 @@ func (self *State) GetStateObject(addr []byte) *StateObject { | ||||
| func (self *State) GetOrNewStateObject(addr []byte) *StateObject { | ||||
| 	stateObject := self.GetStateObject(addr) | ||||
| 	if stateObject == nil { | ||||
| 		stateObject = NewStateObject(addr) | ||||
| 		self.stateObjects[string(addr)] = stateObject | ||||
| 		stateObject = self.NewStateObject(addr) | ||||
| 	} | ||||
| 
 | ||||
| 	return stateObject | ||||
| } | ||||
| 
 | ||||
| func (self *State) NewStateObject(addr []byte) *StateObject { | ||||
| 	stateObject := NewStateObject(addr) | ||||
| 	self.stateObjects[string(addr)] = stateObject | ||||
| 
 | ||||
| 	return stateObject | ||||
| } | ||||
| 
 | ||||
| func (self *State) GetAccount(addr []byte) *StateObject { | ||||
| 	return self.GetOrNewStateObject(addr) | ||||
| } | ||||
|  | ||||
| @ -181,7 +181,6 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea | ||||
| 	coinbase.SetGasPool(block.CalcGasLimit(parent)) | ||||
| 
 | ||||
| 	// Process the transactions on to current block
 | ||||
| 	//sm.ApplyTransactions(block.Coinbase, state, parent, block.Transactions())
 | ||||
| 	sm.ProcessTransactions(coinbase, state, block, parent, block.Transactions()) | ||||
| 
 | ||||
| 	// Block validation
 | ||||
| @ -197,6 +196,9 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// Update the state with pending changes
 | ||||
| 	state.Update() | ||||
| 
 | ||||
| 	if !block.State().Cmp(state) { | ||||
| 		return fmt.Errorf("Invalid merkle root.\nrec: %x\nis:  %x", block.State().trie.Root, state.trie.Root) | ||||
| 	} | ||||
|  | ||||
| @ -4,8 +4,15 @@ import ( | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| 	"math/big" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| type Code []byte | ||||
| 
 | ||||
| func (self Code) String() string { | ||||
| 	return strings.Join(Disassemble(self), " ") | ||||
| } | ||||
| 
 | ||||
| type StateObject struct { | ||||
| 	// Address of the object
 | ||||
| 	address []byte | ||||
| @ -15,8 +22,8 @@ type StateObject struct { | ||||
| 	Nonce      uint64 | ||||
| 	// Contract related attributes
 | ||||
| 	state      *State | ||||
| 	script     []byte | ||||
| 	initScript []byte | ||||
| 	script     Code | ||||
| 	initScript Code | ||||
| 
 | ||||
| 	// Total gas pool is the total amount of gas currently
 | ||||
| 	// left if this object is the coinbase. Gas is directly
 | ||||
| @ -30,12 +37,9 @@ func MakeContract(tx *Transaction, state *State) *StateObject { | ||||
| 	if tx.IsContract() { | ||||
| 		addr := tx.CreationAddress() | ||||
| 
 | ||||
| 		value := tx.Value | ||||
| 		contract := NewContract(addr, value, ZeroHash256) | ||||
| 
 | ||||
| 		contract := state.NewStateObject(addr) | ||||
| 		contract.initScript = tx.Data | ||||
| 
 | ||||
| 		state.UpdateStateObject(contract) | ||||
| 		contract.state = NewState(ethutil.NewTrie(ethutil.Config.Db, "")) | ||||
| 
 | ||||
| 		return contract | ||||
| 	} | ||||
| @ -120,13 +124,13 @@ func (c *StateObject) ReturnGas(gas, price *big.Int, state *State) { | ||||
| func (c *StateObject) AddAmount(amount *big.Int) { | ||||
| 	c.SetAmount(new(big.Int).Add(c.Amount, amount)) | ||||
| 
 | ||||
| 	ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount) | ||||
| 	ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "%x: #%d %v (+ %v)\n", c.Address(), c.Nonce, c.Amount, amount) | ||||
| } | ||||
| 
 | ||||
| func (c *StateObject) SubAmount(amount *big.Int) { | ||||
| 	c.SetAmount(new(big.Int).Sub(c.Amount, amount)) | ||||
| 
 | ||||
| 	ethutil.Config.Log.Printf(ethutil.LogLevelSystem, "%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount) | ||||
| 	ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "%x: #%d %v (- %v)\n", c.Address(), c.Nonce, c.Amount, amount) | ||||
| } | ||||
| 
 | ||||
| func (c *StateObject) SetAmount(amount *big.Int) { | ||||
| @ -197,12 +201,12 @@ func (c *StateObject) Address() []byte { | ||||
| } | ||||
| 
 | ||||
| // Returns the main script body
 | ||||
| func (c *StateObject) Script() []byte { | ||||
| func (c *StateObject) Script() Code { | ||||
| 	return c.script | ||||
| } | ||||
| 
 | ||||
| // Returns the initialization script
 | ||||
| func (c *StateObject) Init() []byte { | ||||
| func (c *StateObject) Init() Code { | ||||
| 	return c.initScript | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -67,13 +67,8 @@ func (self *StateTransition) Receiver() *StateObject { | ||||
| 
 | ||||
| func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject { | ||||
| 	contract := MakeContract(tx, state) | ||||
| 	if contract != nil { | ||||
| 		state.states[string(tx.CreationAddress())] = contract.state | ||||
| 
 | ||||
| 		return contract | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| 	return contract | ||||
| } | ||||
| 
 | ||||
| func (self *StateTransition) UseGas(amount *big.Int) error { | ||||
| @ -137,6 +132,8 @@ func (self *StateTransition) TransitionState() (err error) { | ||||
| 		receiver *StateObject | ||||
| 	) | ||||
| 
 | ||||
| 	ethutil.Config.Log.Printf(ethutil.LogLevelInfo, "(~) %x\n", tx.Hash()) | ||||
| 
 | ||||
| 	// Make sure this transaction's nonce is correct
 | ||||
| 	if sender.Nonce != tx.Nonce { | ||||
| 		return NonceError(tx.Nonce, sender.Nonce) | ||||
| @ -152,15 +149,17 @@ func (self *StateTransition) TransitionState() (err error) { | ||||
| 	defer func() { | ||||
| 		self.RefundGas() | ||||
| 
 | ||||
| 		if sender != nil { | ||||
| 			self.state.UpdateStateObject(sender) | ||||
| 		} | ||||
| 		/* | ||||
| 			if sender != nil { | ||||
| 				self.state.UpdateStateObject(sender) | ||||
| 			} | ||||
| 
 | ||||
| 		if receiver != nil { | ||||
| 			self.state.UpdateStateObject(receiver) | ||||
| 		} | ||||
| 			if receiver != nil { | ||||
| 				self.state.UpdateStateObject(receiver) | ||||
| 			} | ||||
| 
 | ||||
| 		self.state.UpdateStateObject(self.Coinbase()) | ||||
| 			self.state.UpdateStateObject(self.Coinbase()) | ||||
| 		*/ | ||||
| 	}() | ||||
| 
 | ||||
| 	// Increment the nonce for the next transaction
 | ||||
| @ -209,6 +208,7 @@ func (self *StateTransition) TransitionState() (err error) { | ||||
| 		receiver.script = code | ||||
| 	} else { | ||||
| 		if len(receiver.Script()) > 0 { | ||||
| 			fmt.Println(receiver.Script()) | ||||
| 			_, err := self.Eval(receiver.Script(), receiver) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("Error during code execution %v", err) | ||||
|  | ||||
| @ -95,9 +95,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro | ||||
| 	step := 0 | ||||
| 	prevStep := 0 | ||||
| 
 | ||||
| 	if ethutil.Config.Debug { | ||||
| 		ethutil.Config.Log.Debugf("#   op\n") | ||||
| 	} | ||||
| 	ethutil.Config.Log.Debugf("#   op\n") | ||||
| 
 | ||||
| 	for { | ||||
| 		prevStep = step | ||||
| @ -109,9 +107,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro | ||||
| 		val := closure.Get(pc) | ||||
| 		// Get the opcode (it must be an opcode!)
 | ||||
| 		op := OpCode(val.Uint()) | ||||
| 		if ethutil.Config.Debug { | ||||
| 			ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String()) | ||||
| 		} | ||||
| 
 | ||||
| 		ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String()) | ||||
| 
 | ||||
| 		gas := new(big.Int) | ||||
| 		addStepGasUsage := func(amount *big.Int) { | ||||
| @ -525,8 +522,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro | ||||
| 				vm.state.Revert(snapshot) | ||||
| 			} else { | ||||
| 				stack.Push(ethutil.BigD(addr)) | ||||
| 
 | ||||
| 				vm.state.UpdateStateObject(contract) | ||||
| 			} | ||||
| 		case CALL: | ||||
| 			// TODO RE-WRITE
 | ||||
| @ -569,8 +564,6 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro | ||||
| 					} else { | ||||
| 						stack.Push(ethutil.BigTrue) | ||||
| 
 | ||||
| 						vm.state.UpdateStateObject(contract) | ||||
| 
 | ||||
| 						mem.Set(retOffset.Int64(), retSize.Int64(), ret) | ||||
| 					} | ||||
| 				} else { | ||||
| @ -589,9 +582,11 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro | ||||
| 
 | ||||
| 			receiver := vm.state.GetAccount(stack.Pop().Bytes()) | ||||
| 			receiver.AddAmount(closure.object.Amount) | ||||
| 			vm.state.UpdateStateObject(receiver) | ||||
| 
 | ||||
| 			closure.object.state.Purge() | ||||
| 			trie := closure.object.state.trie | ||||
| 			trie.NewIterator().Each(func(key string, v *ethutil.Value) { | ||||
| 				trie.Delete(key) | ||||
| 			}) | ||||
| 
 | ||||
| 			fallthrough | ||||
| 		case STOP: // Stop the closure
 | ||||
|  | ||||
| @ -154,6 +154,8 @@ func (self *Miner) mineNewBlock() { | ||||
| 	// Accumulate the rewards included for this block
 | ||||
| 	stateManager.AccumelateRewards(self.block.State(), self.block) | ||||
| 
 | ||||
| 	self.block.State().Update() | ||||
| 
 | ||||
| 	ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(self.txs), "transactions") | ||||
| 
 | ||||
| 	// Find a valid nonce
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user