Updated chain for filtering
This commit is contained in:
		
							parent
							
								
									2e5d28c73f
								
							
						
					
					
						commit
						a760ce05b9
					
				| @ -142,19 +142,6 @@ func (block *Block) CalcGasLimit(parent *Block) *big.Int { | |||||||
| 	min := big.NewInt(125000) | 	min := big.NewInt(125000) | ||||||
| 
 | 
 | ||||||
| 	return ethutil.BigMax(min, result) | 	return ethutil.BigMax(min, result) | ||||||
| 	/* |  | ||||||
| 		base := new(big.Int) |  | ||||||
| 		base2 := new(big.Int) |  | ||||||
| 		parentGL := bc.CurrentBlock.GasLimit |  | ||||||
| 		parentUsed := bc.CurrentBlock.GasUsed |  | ||||||
| 
 |  | ||||||
| 		base.Mul(parentGL, big.NewInt(1024-1)) |  | ||||||
| 		base2.Mul(parentUsed, big.NewInt(6)) |  | ||||||
| 		base2.Div(base2, big.NewInt(5)) |  | ||||||
| 		base.Add(base, base2) |  | ||||||
| 		base.Div(base, big.NewInt(1024)) |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (block *Block) BlockInfo() BlockInfo { | func (block *Block) BlockInfo() BlockInfo { | ||||||
|  | |||||||
| @ -300,6 +300,8 @@ func (bc *BlockChain) setLastBlock() { | |||||||
| 		bc.genesisBlock.state.Trie.Sync() | 		bc.genesisBlock.state.Trie.Sync() | ||||||
| 		// Prepare the genesis block
 | 		// Prepare the genesis block
 | ||||||
| 		bc.Add(bc.genesisBlock) | 		bc.Add(bc.genesisBlock) | ||||||
|  | 		fk := append([]byte("bloom"), bc.genesisBlock.Hash()...) | ||||||
|  | 		bc.Ethereum.Db().Put(fk, make([]byte, 255)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Set the last know difficulty (might be 0x0 as initial value, Genesis)
 | 	// Set the last know difficulty (might be 0x0 as initial value, Genesis)
 | ||||||
|  | |||||||
| @ -3,16 +3,19 @@ package ethchain | |||||||
| import ( | import ( | ||||||
| 	"container/list" | 	"container/list" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/eth-go/ethcrypto" | ||||||
| 	"github.com/ethereum/eth-go/ethdb" | 	"github.com/ethereum/eth-go/ethdb" | ||||||
|  | 	"github.com/ethereum/eth-go/ethreact" | ||||||
| 	"github.com/ethereum/eth-go/ethutil" | 	"github.com/ethereum/eth-go/ethutil" | ||||||
| 	"github.com/ethereum/eth-go/ethwire" | 	"github.com/ethereum/eth-go/ethwire" | ||||||
| 	"testing" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Implement our EthTest Manager
 | // Implement our EthTest Manager
 | ||||||
| type TestManager struct { | type TestManager struct { | ||||||
| 	stateManager *StateManager | 	stateManager *StateManager | ||||||
| 	reactor      *ethutil.ReactorEngine | 	reactor      *ethreact.ReactorEngine | ||||||
| 
 | 
 | ||||||
| 	txPool     *TxPool | 	txPool     *TxPool | ||||||
| 	blockChain *BlockChain | 	blockChain *BlockChain | ||||||
| @ -47,16 +50,24 @@ func (tm *TestManager) StateManager() *StateManager { | |||||||
| 	return tm.stateManager | 	return tm.stateManager | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (tm *TestManager) Reactor() *ethutil.ReactorEngine { | func (tm *TestManager) Reactor() *ethreact.ReactorEngine { | ||||||
| 	return tm.reactor | 	return tm.reactor | ||||||
| } | } | ||||||
| func (tm *TestManager) Broadcast(msgType ethwire.MsgType, data []interface{}) { | func (tm *TestManager) Broadcast(msgType ethwire.MsgType, data []interface{}) { | ||||||
| 	fmt.Println("Broadcast not implemented") | 	fmt.Println("Broadcast not implemented") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewTestManager() *TestManager { | func (tm *TestManager) ClientIdentity() ethwire.ClientIdentity { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | func (tm *TestManager) KeyManager() *ethcrypto.KeyManager { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "", "ETH") | func (tm *TestManager) Db() ethutil.Database { return nil } | ||||||
|  | 
 | ||||||
|  | func NewTestManager() *TestManager { | ||||||
|  | 	ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "ETH") | ||||||
| 
 | 
 | ||||||
| 	db, err := ethdb.NewMemDatabase() | 	db, err := ethdb.NewMemDatabase() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -66,7 +77,7 @@ func NewTestManager() *TestManager { | |||||||
| 	ethutil.Config.Db = db | 	ethutil.Config.Db = db | ||||||
| 
 | 
 | ||||||
| 	testManager := &TestManager{} | 	testManager := &TestManager{} | ||||||
| 	testManager.reactor = ethutil.NewReactorEngine() | 	testManager.reactor = ethreact.New() | ||||||
| 
 | 
 | ||||||
| 	testManager.txPool = NewTxPool(testManager) | 	testManager.txPool = NewTxPool(testManager) | ||||||
| 	testManager.blockChain = NewBlockChain(testManager) | 	testManager.blockChain = NewBlockChain(testManager) | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ type EthManager interface { | |||||||
| 	Peers() *list.List | 	Peers() *list.List | ||||||
| 	KeyManager() *ethcrypto.KeyManager | 	KeyManager() *ethcrypto.KeyManager | ||||||
| 	ClientIdentity() ethwire.ClientIdentity | 	ClientIdentity() ethwire.ClientIdentity | ||||||
|  | 	Db() ethutil.Database | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type StateManager struct { | type StateManager struct { | ||||||
| @ -235,7 +236,12 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { | |||||||
| 
 | 
 | ||||||
| 		// Add the block to the chain
 | 		// Add the block to the chain
 | ||||||
| 		sm.bc.Add(block) | 		sm.bc.Add(block) | ||||||
| 		sm.notifyChanges(state) | 
 | ||||||
|  | 		// Create a bloom bin for this block
 | ||||||
|  | 		filter := sm.createBloomFilter(state) | ||||||
|  | 		// Persist the data
 | ||||||
|  | 		fk := append([]byte("bloom"), block.Hash()...) | ||||||
|  | 		sm.Ethereum.Db().Put(fk, filter.Bin()) | ||||||
| 
 | 
 | ||||||
| 		statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash()) | 		statelogger.Infof("Added block #%d (%x)\n", block.Number, block.Hash()) | ||||||
| 		if dontReact == false { | 		if dontReact == false { | ||||||
| @ -363,14 +369,74 @@ func (sm *StateManager) Stop() { | |||||||
| 	sm.bc.Stop() | 	sm.bc.Stop() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (sm *StateManager) notifyChanges(state *ethstate.State) { | // Manifest will handle both creating notifications and generating bloom bin data
 | ||||||
|  | func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter { | ||||||
|  | 	bloomf := NewBloomFilter(nil) | ||||||
|  | 
 | ||||||
| 	for addr, stateObject := range state.Manifest().ObjectChanges { | 	for addr, stateObject := range state.Manifest().ObjectChanges { | ||||||
|  | 		// Set the bloom filter's bin
 | ||||||
|  | 		bloomf.Set([]byte(addr)) | ||||||
|  | 
 | ||||||
| 		sm.Ethereum.Reactor().Post("object:"+addr, stateObject) | 		sm.Ethereum.Reactor().Post("object:"+addr, stateObject) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges { | 	for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges { | ||||||
| 		for addr, value := range mappedObjects { | 		for addr, value := range mappedObjects { | ||||||
|  | 			// Set the bloom filter's bin
 | ||||||
|  | 			bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr))) | ||||||
|  | 
 | ||||||
| 			sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, ðstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value}) | 			sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, ðstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value}) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	return bloomf | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message, err error) { | ||||||
|  | 	if !sm.bc.HasBlock(block.PrevHash) { | ||||||
|  | 		return nil, ParentError(block.PrevHash) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sm.lastAttemptedBlock = block | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		parent = sm.bc.GetBlock(block.PrevHash) | ||||||
|  | 		state  = parent.State().Copy() | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	defer state.Reset() | ||||||
|  | 
 | ||||||
|  | 	if ethutil.Config.Diff && ethutil.Config.DiffType == "all" { | ||||||
|  | 		fmt.Printf("## %x %x ##\n", block.Hash(), block.Number) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	receipts, err := sm.ApplyDiff(state, parent, block) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	txSha := CreateTxSha(receipts) | ||||||
|  | 	if bytes.Compare(txSha, block.TxSha) != 0 { | ||||||
|  | 		return nil, fmt.Errorf("Error validating tx sha. Received %x, got %x", block.TxSha, txSha) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Block validation
 | ||||||
|  | 	if err = sm.ValidateBlock(block); err != nil { | ||||||
|  | 		statelogger.Errorln("Error validating block:", err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// I'm not sure, but I don't know if there should be thrown
 | ||||||
|  | 	// any errors at this time.
 | ||||||
|  | 	if err = sm.AccumelateRewards(state, block); err != nil { | ||||||
|  | 		statelogger.Errorln("Error accumulating reward", err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if !block.State().Cmp(state) { | ||||||
|  | 		err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis:  %x", block.State().Trie.Root, state.Trie.Root) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return state.Manifest().Messages, nil | ||||||
| } | } | ||||||
|  | |||||||
| @ -211,6 +211,13 @@ func (self *StateTransition) TransitionState() (err error) { | |||||||
| 		snapshot = self.state.Copy() | 		snapshot = self.state.Copy() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	msg := self.state.Manifest().AddMessage(ðstate.Message{ | ||||||
|  | 		To: receiver.Address(), From: sender.Address(), | ||||||
|  | 		Input:  self.tx.Data, | ||||||
|  | 		Origin: sender.Address(), | ||||||
|  | 		Block:  self.block.Hash(), Timestamp: self.block.Time, Coinbase: self.block.Coinbase, Number: self.block.Number, | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
| 	// Process the init code and create 'valid' contract
 | 	// Process the init code and create 'valid' contract
 | ||||||
| 	if IsContractAddr(self.receiver) { | 	if IsContractAddr(self.receiver) { | ||||||
| 		// Evaluate the initialization script
 | 		// Evaluate the initialization script
 | ||||||
| @ -226,14 +233,17 @@ func (self *StateTransition) TransitionState() (err error) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		receiver.Code = code | 		receiver.Code = code | ||||||
|  | 		msg.Output = code | ||||||
| 	} else { | 	} else { | ||||||
| 		if len(receiver.Code) > 0 { | 		if len(receiver.Code) > 0 { | ||||||
| 			_, err = self.Eval(receiver.Code, receiver, "code") | 			ret, err := self.Eval(receiver.Code, receiver, "code") | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				self.state.Set(snapshot) | 				self.state.Set(snapshot) | ||||||
| 
 | 
 | ||||||
| 				return fmt.Errorf("Error during code execution %v", err) | 				return fmt.Errorf("Error during code execution %v", err) | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			msg.Output = ret | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,8 +1,9 @@ | |||||||
| package ethchain | package ethchain | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/ethereum/eth-go/ethstate" |  | ||||||
| 	"math/big" | 	"math/big" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/eth-go/ethstate" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type VMEnv struct { | type VMEnv struct { | ||||||
| @ -25,5 +26,6 @@ func (self *VMEnv) PrevHash() []byte       { return self.block.PrevHash } | |||||||
| func (self *VMEnv) Coinbase() []byte       { return self.block.Coinbase } | func (self *VMEnv) Coinbase() []byte       { return self.block.Coinbase } | ||||||
| func (self *VMEnv) Time() int64            { return self.block.Time } | func (self *VMEnv) Time() int64            { return self.block.Time } | ||||||
| func (self *VMEnv) Difficulty() *big.Int   { return self.block.Difficulty } | func (self *VMEnv) Difficulty() *big.Int   { return self.block.Difficulty } | ||||||
|  | func (self *VMEnv) BlockHash() []byte      { return self.block.Hash() } | ||||||
| func (self *VMEnv) Value() *big.Int        { return self.tx.Value } | func (self *VMEnv) Value() *big.Int        { return self.tx.Value } | ||||||
| func (self *VMEnv) State() *ethstate.State { return self.state } | func (self *VMEnv) State() *ethstate.State { return self.state } | ||||||
|  | |||||||
| @ -44,8 +44,8 @@ type Ethereum struct { | |||||||
| 	// Channel for shutting down the ethereum
 | 	// Channel for shutting down the ethereum
 | ||||||
| 	shutdownChan chan bool | 	shutdownChan chan bool | ||||||
| 	quit         chan bool | 	quit         chan bool | ||||||
|  | 
 | ||||||
| 	// DB interface
 | 	// DB interface
 | ||||||
| 	//db *ethdb.LDBDatabase
 |  | ||||||
| 	db ethutil.Database | 	db ethutil.Database | ||||||
| 	// State manager for processing new blocks and managing the over all states
 | 	// State manager for processing new blocks and managing the over all states
 | ||||||
| 	stateManager *ethchain.StateManager | 	stateManager *ethchain.StateManager | ||||||
| @ -149,6 +149,9 @@ func (s *Ethereum) StateManager() *ethchain.StateManager { | |||||||
| func (s *Ethereum) TxPool() *ethchain.TxPool { | func (s *Ethereum) TxPool() *ethchain.TxPool { | ||||||
| 	return s.txPool | 	return s.txPool | ||||||
| } | } | ||||||
|  | func (self *Ethereum) Db() ethutil.Database { | ||||||
|  | 	return self.db | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| func (s *Ethereum) ServerCaps() Caps { | func (s *Ethereum) ServerCaps() Caps { | ||||||
| 	return s.serverCaps | 	return s.serverCaps | ||||||
|  | |||||||
| @ -29,5 +29,6 @@ func (self *VMEnv) PrevHash() []byte       { return self.block.PrevHash } | |||||||
| func (self *VMEnv) Coinbase() []byte       { return self.block.Coinbase } | func (self *VMEnv) Coinbase() []byte       { return self.block.Coinbase } | ||||||
| func (self *VMEnv) Time() int64            { return self.block.Time } | func (self *VMEnv) Time() int64            { return self.block.Time } | ||||||
| func (self *VMEnv) Difficulty() *big.Int   { return self.block.Difficulty } | func (self *VMEnv) Difficulty() *big.Int   { return self.block.Difficulty } | ||||||
|  | func (self *VMEnv) BlockHash() []byte      { return self.block.Hash() } | ||||||
| func (self *VMEnv) Value() *big.Int        { return self.value } | func (self *VMEnv) Value() *big.Int        { return self.value } | ||||||
| func (self *VMEnv) State() *ethstate.State { return self.state } | func (self *VMEnv) State() *ethstate.State { return self.state } | ||||||
|  | |||||||
| @ -211,50 +211,13 @@ func (self *State) Update() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (self *State) Manifest() *Manifest { | ||||||
|  | 	return self.manifest | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Debug stuff
 | // Debug stuff
 | ||||||
| func (self *State) CreateOutputForDiff() { | func (self *State) CreateOutputForDiff() { | ||||||
| 	for _, stateObject := range self.stateObjects { | 	for _, stateObject := range self.stateObjects { | ||||||
| 		stateObject.CreateOutputForDiff() | 		stateObject.CreateOutputForDiff() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func (self *State) Manifest() *Manifest { |  | ||||||
| 	return self.manifest |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Object manifest
 |  | ||||||
| //
 |  | ||||||
| // The object manifest is used to keep changes to the state so we can keep track of the changes
 |  | ||||||
| // that occurred during a state transitioning phase.
 |  | ||||||
| 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 |  | ||||||
| 
 |  | ||||||
| 	ObjectChanges  map[string]*StateObject |  | ||||||
| 	StorageChanges map[string]map[string]*big.Int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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 |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -2,15 +2,16 @@ package ethutil | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	_ "encoding/binary" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	_ "log" |  | ||||||
| 	_ "math" |  | ||||||
| 	"math/big" | 	"math/big" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type RlpEncodable interface { | type RlpEncode interface { | ||||||
| 	RlpEncode() []byte | 	RlpEncode() []byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type RlpEncodeDecode interface { | ||||||
|  | 	RlpEncode | ||||||
| 	RlpValue() []interface{} | 	RlpValue() []interface{} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -74,6 +74,30 @@ func (val *Value) Uint() uint64 { | |||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (val *Value) Int() int64 { | ||||||
|  | 	if Val, ok := val.Val.(int8); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.(int16); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.(int32); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.(int64); ok { | ||||||
|  | 		return Val | ||||||
|  | 	} else if Val, ok := val.Val.(int); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.(float32); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.(float64); ok { | ||||||
|  | 		return int64(Val) | ||||||
|  | 	} else if Val, ok := val.Val.([]byte); ok { | ||||||
|  | 		return new(big.Int).SetBytes(Val).Int64() | ||||||
|  | 	} else if Val, ok := val.Val.(*big.Int); ok { | ||||||
|  | 		return Val.Int64() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (val *Value) Byte() byte { | func (val *Value) Byte() byte { | ||||||
| 	if Val, ok := val.Val.(byte); ok { | 	if Val, ok := val.Val.(byte); ok { | ||||||
| 		return Val | 		return Val | ||||||
|  | |||||||
| @ -3,9 +3,10 @@ package ethvm | |||||||
| // TODO Re write VM to use values instead of big integers?
 | // TODO Re write VM to use values instead of big integers?
 | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"math/big" | ||||||
|  | 
 | ||||||
| 	"github.com/ethereum/eth-go/ethstate" | 	"github.com/ethereum/eth-go/ethstate" | ||||||
| 	"github.com/ethereum/eth-go/ethutil" | 	"github.com/ethereum/eth-go/ethutil" | ||||||
| 	"math/big" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type ClosureRef interface { | type ClosureRef interface { | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								ethvm/vm.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								ethvm/vm.go
									
									
									
									
									
								
							| @ -52,6 +52,7 @@ type Environment interface { | |||||||
| 	Time() int64 | 	Time() int64 | ||||||
| 	Difficulty() *big.Int | 	Difficulty() *big.Int | ||||||
| 	Value() *big.Int | 	Value() *big.Int | ||||||
|  | 	BlockHash() []byte | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Object interface { | type Object interface { | ||||||
| @ -696,6 +697,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { | |||||||
| 
 | 
 | ||||||
| 			self.Printf(" (*) %x", addr).Endl() | 			self.Printf(" (*) %x", addr).Endl() | ||||||
| 
 | 
 | ||||||
|  | 			msg := self.env.State().Manifest().AddMessage(ðstate.Message{ | ||||||
|  | 				To: addr, From: closure.Address(), | ||||||
|  | 				Origin: self.env.Origin(), | ||||||
|  | 				Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
| 			// Create a new contract
 | 			// Create a new contract
 | ||||||
| 			contract := self.env.State().NewStateObject(addr) | 			contract := self.env.State().NewStateObject(addr) | ||||||
| 			if contract.Balance.Cmp(value) >= 0 { | 			if contract.Balance.Cmp(value) >= 0 { | ||||||
| @ -704,7 +711,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { | |||||||
| 
 | 
 | ||||||
| 				// Set the init script
 | 				// Set the init script
 | ||||||
| 				initCode := mem.Get(offset.Int64(), size.Int64()) | 				initCode := mem.Get(offset.Int64(), size.Int64()) | ||||||
| 				//fmt.Printf("%x\n", initCode)
 | 				msg.Input = initCode | ||||||
|  | 
 | ||||||
| 				// Transfer all remaining gas to the new
 | 				// Transfer all remaining gas to the new
 | ||||||
| 				// contract so it may run the init script
 | 				// contract so it may run the init script
 | ||||||
| 				gas := new(big.Int).Set(closure.Gas) | 				gas := new(big.Int).Set(closure.Gas) | ||||||
| @ -728,7 +736,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { | |||||||
| 				self.Printf("CREATE err %v", err) | 				self.Printf("CREATE err %v", err) | ||||||
| 			} else { | 			} else { | ||||||
| 				stack.Push(ethutil.BigD(addr)) | 				stack.Push(ethutil.BigD(addr)) | ||||||
| 				self.Printf("CREATE success") | 
 | ||||||
|  | 				msg.Output = contract.Code | ||||||
| 			} | 			} | ||||||
| 			self.Endl() | 			self.Endl() | ||||||
| 
 | 
 | ||||||
| @ -752,6 +761,13 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { | |||||||
| 			// Get the arguments from the memory
 | 			// Get the arguments from the memory
 | ||||||
| 			args := mem.Get(inOffset.Int64(), inSize.Int64()) | 			args := mem.Get(inOffset.Int64(), inSize.Int64()) | ||||||
| 
 | 
 | ||||||
|  | 			msg := self.env.State().Manifest().AddMessage(ðstate.Message{ | ||||||
|  | 				To: addr.Bytes(), From: closure.Address(), | ||||||
|  | 				Input:  args, | ||||||
|  | 				Origin: self.env.Origin(), | ||||||
|  | 				Block:  self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
| 			if closure.object.Balance.Cmp(value) < 0 { | 			if closure.object.Balance.Cmp(value) < 0 { | ||||||
| 				vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance) | 				vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance) | ||||||
| 
 | 
 | ||||||
| @ -782,6 +798,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { | |||||||
| 					mem.Set(retOffset.Int64(), retSize.Int64(), ret) | 					mem.Set(retOffset.Int64(), retSize.Int64(), ret) | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				msg.Output = ret | ||||||
|  | 
 | ||||||
| 				// Debug hook
 | 				// Debug hook
 | ||||||
| 				if self.Dbg != nil { | 				if self.Dbg != nil { | ||||||
| 					self.Dbg.SetCode(closure.Code) | 					self.Dbg.SetCode(closure.Code) | ||||||
|  | |||||||
| @ -6,9 +6,10 @@ import ( | |||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/ethereum/eth-go/ethutil" |  | ||||||
| 	"net" | 	"net" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/eth-go/ethutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Connection interface describing the methods required to implement the wire protocol.
 | // Connection interface describing the methods required to implement the wire protocol.
 | ||||||
| @ -109,7 +110,7 @@ func (self *Connection) Write(typ MsgType, v ...interface{}) error { | |||||||
| 
 | 
 | ||||||
| 	slice := [][]interface{}{[]interface{}{byte(typ)}} | 	slice := [][]interface{}{[]interface{}{byte(typ)}} | ||||||
| 	for _, value := range v { | 	for _, value := range v { | ||||||
| 		if encodable, ok := value.(ethutil.RlpEncodable); ok { | 		if encodable, ok := value.(ethutil.RlpEncodeDecode); ok { | ||||||
| 			slice = append(slice, encodable.RlpValue()) | 			slice = append(slice, encodable.RlpValue()) | ||||||
| 		} else if raw, ok := value.([]interface{}); ok { | 		} else if raw, ok := value.([]interface{}); ok { | ||||||
| 			slice = append(slice, raw) | 			slice = append(slice, raw) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user