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