good morning!!!!

Skip to content
Snippets Groups Projects
Commit 21724f7e authored by Jeffrey Wilcke's avatar Jeffrey Wilcke
Browse files

Added manifest changes and changed closures

parent 38d6b67b
No related branches found
No related tags found
No related merge requests found
...@@ -7,13 +7,6 @@ import ( ...@@ -7,13 +7,6 @@ import (
"math/big" "math/big"
) )
type Callee interface {
}
type Reference interface {
Callee
}
type ClosureRef interface { type ClosureRef interface {
ReturnGas(*big.Int, *big.Int, *State) ReturnGas(*big.Int, *big.Int, *State)
Address() []byte Address() []byte
...@@ -24,8 +17,8 @@ type ClosureRef interface { ...@@ -24,8 +17,8 @@ type ClosureRef interface {
// Basic inline closure object which implement the 'closure' interface // Basic inline closure object which implement the 'closure' interface
type Closure struct { type Closure struct {
callee ClosureRef callee *StateObject
object ClosureRef object *StateObject
Script []byte Script []byte
State *State State *State
...@@ -37,7 +30,7 @@ type Closure struct { ...@@ -37,7 +30,7 @@ type Closure struct {
} }
// Create a new closure for the given data items // Create a new closure for the given data items
func NewClosure(callee, object ClosureRef, script []byte, state *State, gas, price, val *big.Int) *Closure { func NewClosure(callee, object *StateObject, script []byte, state *State, gas, price, val *big.Int) *Closure {
c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil} c := &Closure{callee: callee, object: object, Script: script, State: state, Args: nil}
// In most cases gas, price and value are pointers to transaction objects // In most cases gas, price and value are pointers to transaction objects
...@@ -108,11 +101,11 @@ func (c *Closure) ReturnGas(gas, price *big.Int, state *State) { ...@@ -108,11 +101,11 @@ func (c *Closure) ReturnGas(gas, price *big.Int, state *State) {
c.Gas.Add(c.Gas, gas) c.Gas.Add(c.Gas, gas)
} }
func (c *Closure) Object() ClosureRef { func (c *Closure) Object() *StateObject {
return c.object return c.object
} }
func (c *Closure) Callee() ClosureRef { func (c *Closure) Callee() *StateObject {
return c.callee return c.callee
} }
......
...@@ -51,9 +51,7 @@ type StateManager struct { ...@@ -51,9 +51,7 @@ type StateManager struct {
// results // results
compState *State compState *State
// It's generally know that a map is faster for small lookups than arrays manifest *Manifest
// we'll eventually have to make a decision if the map grows too large
watchedAddresses map[string]bool
} }
func NewStateManager(ethereum EthManager) *StateManager { func NewStateManager(ethereum EthManager) *StateManager {
...@@ -64,7 +62,7 @@ func NewStateManager(ethereum EthManager) *StateManager { ...@@ -64,7 +62,7 @@ func NewStateManager(ethereum EthManager) *StateManager {
Ethereum: ethereum, Ethereum: ethereum,
stateObjectCache: NewStateObjectCache(), stateObjectCache: NewStateObjectCache(),
bc: ethereum.BlockChain(), bc: ethereum.BlockChain(),
watchedAddresses: make(map[string]bool), manifest: NewManifest(),
} }
sm.procState = ethereum.BlockChain().CurrentBlock.State() sm.procState = ethereum.BlockChain().CurrentBlock.State()
return sm return sm
...@@ -112,7 +110,6 @@ func (sm *StateManager) MakeContract(tx *Transaction) *StateObject { ...@@ -112,7 +110,6 @@ func (sm *StateManager) MakeContract(tx *Transaction) *StateObject {
func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) { func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) {
// Process each transaction/contract // Process each transaction/contract
for _, tx := range txs { for _, tx := range txs {
fmt.Printf("Processing Tx: %x\n", tx.Hash())
// If there's no recipient, it's a contract // If there's no recipient, it's a contract
// Check if this is a contract creation traction and if so // Check if this is a contract creation traction and if so
// create a contract of this tx. // create a contract of this tx.
...@@ -122,7 +119,6 @@ func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) { ...@@ -122,7 +119,6 @@ func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) {
contract := sm.MakeContract(tx) contract := sm.MakeContract(tx)
if contract != nil { if contract != nil {
sm.EvalScript(contract.Init(), contract, tx, block) sm.EvalScript(contract.Init(), contract, tx, block)
fmt.Printf("state root of contract %x\n", contract.State().Root())
} else { } else {
ethutil.Config.Log.Infoln("[STATE] Unable to create contract") ethutil.Config.Log.Infoln("[STATE] Unable to create contract")
} }
...@@ -214,6 +210,10 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error { ...@@ -214,6 +210,10 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error {
ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash()) ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash())
if dontReact == false { if dontReact == false {
sm.Ethereum.Reactor().Post("newBlock", block) sm.Ethereum.Reactor().Post("newBlock", block)
sm.notifyChanges()
sm.manifest.Reset()
} }
} else { } else {
fmt.Println("total diff failed") fmt.Println("total diff failed")
...@@ -337,22 +337,53 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans ...@@ -337,22 +337,53 @@ func (sm *StateManager) EvalScript(script []byte, object *StateObject, tx *Trans
// Update the account (refunds) // Update the account (refunds)
sm.procState.UpdateStateObject(account) sm.procState.UpdateStateObject(account)
sm.Changed(account) sm.manifest.AddObjectChange(account)
sm.procState.UpdateStateObject(object) sm.procState.UpdateStateObject(object)
sm.Changed(object) sm.manifest.AddObjectChange(object)
}
func (sm *StateManager) notifyChanges() {
for addr, stateObject := range sm.manifest.objectChanges {
sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
} }
// Watch a specific address for stateObjectAddr, mappedObjects := range sm.manifest.storageChanges {
func (sm *StateManager) Watch(addr []byte) { for addr, value := range mappedObjects {
if !sm.watchedAddresses[string(addr)] { sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, value.String())
sm.watchedAddresses[string(addr)] = true
} }
} }
}
type Manifest struct {
// XXX These will be handy in the future. Not important for now.
objectAddresses map[string]bool
storageAddresses map[string]map[string]bool
// The following objects are used when changing a value and using the "watched" attribute objectChanges map[string]*StateObject
// to determine whether the reactor should be used to notify any subscribers on the address storageChanges map[string]map[string]*big.Int
func (sm *StateManager) Changed(stateObject *StateObject) {
if sm.watchedAddresses[string(stateObject.Address())] {
sm.Ethereum.Reactor().Post("addressChanged", stateObject)
} }
func NewManifest() *Manifest {
m := &Manifest{objectAddresses: make(map[string]bool), storageAddresses: make(map[string]map[string]bool)}
m.Reset()
return m
}
func (m *Manifest) Reset() {
m.objectChanges = make(map[string]*StateObject)
m.storageChanges = make(map[string]map[string]*big.Int)
}
func (m *Manifest) AddObjectChange(stateObject *StateObject) {
m.objectChanges[string(stateObject.Address())] = stateObject
}
func (m *Manifest) AddStorageChange(stateObject *StateObject, storageAddr []byte, storage *big.Int) {
if m.storageChanges[string(stateObject.Address())] == nil {
m.storageChanges[string(stateObject.Address())] = make(map[string]*big.Int)
}
m.storageChanges[string(stateObject.Address())][string(storageAddr)] = storage
} }
...@@ -411,6 +411,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro ...@@ -411,6 +411,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
require(2) require(2)
val, loc := stack.Popn() val, loc := stack.Popn()
closure.SetMem(loc, ethutil.NewValue(val)) closure.SetMem(loc, ethutil.NewValue(val))
// Add the change to manifest
vm.stateManager.manifest.AddStorageChange(closure.Object(), loc.Bytes(), val)
case oJUMP: case oJUMP:
require(1) require(1)
pc = stack.Pop() pc = stack.Pop()
...@@ -492,7 +495,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro ...@@ -492,7 +495,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
} }
closure.Gas.Sub(closure.Gas, gas) closure.Gas.Sub(closure.Gas, gas)
// Create a new callable closure // Create a new callable closure
closure := NewClosure(closure, contract, contract.script, vm.state, gas, closure.Price, value) closure := NewClosure(closure.Object(), contract, contract.script, vm.state, gas, closure.Price, value)
// Executer the closure and get the return value (if any) // Executer the closure and get the return value (if any)
ret, err := closure.Call(vm, args, hook) ret, err := closure.Call(vm, args, hook)
if err != nil { if err != nil {
...@@ -502,7 +505,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro ...@@ -502,7 +505,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
} else { } else {
stack.Push(ethutil.BigTrue) stack.Push(ethutil.BigTrue)
// Notify of the changes // Notify of the changes
vm.stateManager.Changed(contract) vm.stateManager.manifest.AddObjectChange(contract)
} }
mem.Set(retOffset.Int64(), retSize.Int64(), ret) mem.Set(retOffset.Int64(), retSize.Int64(), ret)
......
...@@ -2,7 +2,6 @@ package ethminer ...@@ -2,7 +2,6 @@ package ethminer
import ( import (
"bytes" "bytes"
"fmt"
"github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire" "github.com/ethereum/eth-go/ethwire"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment