From 399256b38403f2e95312250d49fca3cada8956b8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Sep 2014 22:11:05 +0200 Subject: VM execution fixes Refactoring caused executing issues --- ethchain/block_chain.go | 8 +++----- ethchain/state_manager.go | 19 ++++++++++++------ ethereum.go | 3 ++- ethvm/stack.go | 6 +++--- ethvm/vm.go | 49 ++++++++++++++++++++++++----------------------- ethwire/messaging.go | 4 +++- peer.go | 19 ++++++++---------- 7 files changed, 57 insertions(+), 51 deletions(-) diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 5d0d652df..1e29f1188 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -148,6 +148,9 @@ func AddTestNetFunds(block *Block) { } func (bc *BlockChain) setLastBlock() { + // Prep genesis + AddTestNetFunds(bc.genesisBlock) + data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) if len(data) != 0 { block := NewBlockFromBytes(data) @@ -155,12 +158,7 @@ func (bc *BlockChain) setLastBlock() { bc.LastBlockHash = block.Hash() bc.LastBlockNumber = block.Number.Uint64() - if bc.LastBlockNumber == 0 { - bc.genesisBlock = block - } } else { - AddTestNetFunds(bc.genesisBlock) - bc.genesisBlock.state.Trie.Sync() // Prepare the genesis block bc.Add(bc.genesisBlock) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 1ccaa560f..b0ea754f4 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -5,6 +5,7 @@ import ( "container/list" "fmt" "math/big" + "os" "sync" "time" @@ -154,6 +155,10 @@ done: if i < len(block.Receipts()) { original := block.Receipts()[i] if !original.Cmp(receipt) { + if ethutil.Config.Diff { + os.Exit(1) + } + return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash()) } } @@ -307,14 +312,16 @@ func (sm *StateManager) ValidateBlock(block *Block) error { // Check each uncle's previous hash. In order for it to be valid // is if it has the same block hash as the current - previousBlock := sm.bc.GetBlock(block.PrevHash) - for _, uncle := range block.Uncles { - if bytes.Compare(uncle.PrevHash, previousBlock.PrevHash) != 0 { - return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x", previousBlock.PrevHash, uncle.PrevHash) + parent := sm.bc.GetBlock(block.PrevHash) + /* + for _, uncle := range block.Uncles { + if bytes.Compare(uncle.PrevHash,parent.PrevHash) != 0 { + return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x",parent.PrevHash, uncle.PrevHash) + } } - } + */ - diff := block.Time - previousBlock.Time + diff := block.Time - parent.Time if diff < 0 { return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time) } diff --git a/ethereum.go b/ethereum.go index fdfb59b09..8d62fa9f2 100644 --- a/ethereum.go +++ b/ethereum.go @@ -23,7 +23,8 @@ import ( const ( seedTextFileUri string = "http://www.ethereum.org/servers.poc3.txt" - seedNodeAddress = "54.76.56.74:30303" + //seedNodeAddress = "54.76.56.74:30303" + seedNodeAddress = "localhost:30303" ) var ethlogger = ethlog.NewLogger("SERV") diff --git a/ethvm/stack.go b/ethvm/stack.go index 82dd612c2..4ac023fb9 100644 --- a/ethvm/stack.go +++ b/ethvm/stack.go @@ -65,13 +65,13 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) { } func (st *Stack) Swapn(n int) (*big.Int, *big.Int) { - st.data[n], st.data[0] = st.data[0], st.data[n] + st.data[len(st.data)-n], st.data[len(st.data)-1] = st.data[len(st.data)-1], st.data[len(st.data)-n] - return st.data[n], st.data[0] + return st.data[len(st.data)-n], st.data[len(st.data)-1] } func (st *Stack) Dupn(n int) *big.Int { - st.Push(st.data[n]) + st.Push(st.data[len(st.data)-n]) return st.Peek() } diff --git a/ethvm/vm.go b/ethvm/vm.go index 2c516f4f8..cfba3820b 100644 --- a/ethvm/vm.go +++ b/ethvm/vm.go @@ -63,7 +63,7 @@ func New(env Environment) *Vm { lt = LogTyDiff } - return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()} + return &Vm{env: env, logTy: lt, Recoverable: false, queue: list.New()} } func calcMemSize(off, l *big.Int) *big.Int { @@ -132,15 +132,13 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { // XXX Leave this Println intact. Don't change this to the log system. // Used for creating diffs between implementations if self.logTy == LogTyDiff { - /* - switch op { - case STOP, RETURN, SUICIDE: - closure.object.EachStorage(func(key string, value *ethutil.Value) { - value.Decode() - fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes()) - }) - } - */ + switch op { + case STOP, RETURN, SUICIDE: + closure.object.EachStorage(func(key string, value *ethutil.Value) { + value.Decode() + fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes()) + }) + } b := pc.Bytes() if len(b) == 0 { @@ -230,13 +228,15 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { } if newMemSize.Cmp(ethutil.Big0) > 0 { - //newMemSize = (newMemSize + 31) / 32 * 32 - newMemSize = newMemSize.Add(newMemSize, u256(31)).Div(newMemSize, u256(32)).Mul(newMemSize, u256(32)) - //if newMemSize > uint64(mem.Len()) { + newMemSize.Add(newMemSize, u256(31)) + newMemSize.Div(newMemSize, u256(32)) + newMemSize.Mul(newMemSize, u256(32)) + if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 { - newMemSize = newMemSize.Sub(newMemSize, u256(int64(mem.Len()))) - memGasUsage := newMemSize.Mul(GasMemory, newMemSize).Div(newMemSize, u256(32)) - //m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32 + memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len()))) + memGasUsage.Mul(GasMemory, memGasUsage) + memGasUsage.Div(memGasUsage, u256(32)) + addStepGasUsage(memGasUsage) } } @@ -669,12 +669,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { require(1) stack.Pop() case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: - n := int(op - DUP1) + n := int(op - DUP1 + 1) stack.Dupn(n) self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes()) case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: - n := int(op - SWAP1) + n := int(op - SWAP1 + 2) x, y := stack.Swapn(n) self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes()) @@ -694,12 +694,12 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" => 0x%x", val) case MSTORE8: require(2) - val, mStart := stack.Popn() - //base.And(val, new(big.Int).SetInt64(0xff)) - //mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(base, 256)) - mem.store[mStart.Int64()] = byte(val.Int64() & 0xff) + off := stack.Pop() + val := stack.Pop() - self.Printf(" => 0x%x", val) + mem.store[off.Int64()] = byte(val.Int64() & 0xff) + + self.Printf(" => [%v] 0x%x", off, val) case SLOAD: require(1) loc := stack.Pop() @@ -955,6 +955,7 @@ func (self *Message) Addr() []byte { } func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err error) { + fmt.Printf("%x %x\n", codeAddr[0:4], self.address[0:4]) queue := self.vm.queue self.vm.queue = list.New() @@ -990,7 +991,7 @@ func (self *Message) Exec(codeAddr []byte, caller ClosureRef) (ret []byte, err e code := self.vm.env.State().GetCode(codeAddr) // Create a new callable closure - c := NewClosure(msg, caller, object, code, self.gas, self.price) + c := NewClosure(msg, caller, stateObject, code, self.gas, self.price) // Executer the closure and get the return value (if any) ret, _, err = c.Call(self.vm, self.input) diff --git a/ethwire/messaging.go b/ethwire/messaging.go index 67a866f73..bee6dd526 100644 --- a/ethwire/messaging.go +++ b/ethwire/messaging.go @@ -282,8 +282,10 @@ func ReadMessages(conn net.Conn) (msgs []*Msg, err error) { var buff []byte var totalBytes int for { + // This is a bit of a cheat actually to make buffering extremely fast. + defer recover() // Give buffering some time - conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) + conn.SetReadDeadline(time.Now().Add(5 * time.Millisecond)) // Create a new temporarily buffer b := make([]byte, 1440) // Wait for a message from this peer diff --git a/peer.go b/peer.go index 32885aed8..69aa4b668 100644 --- a/peer.go +++ b/peer.go @@ -497,18 +497,16 @@ func (p *Peer) HandleInbound() { p.lastBlockReceived = time.Now() } + var err error blockPool.CheckLinkAndProcess(func(block *ethchain.Block) { - err := p.ethereum.StateManager().Process(block, false) - if err != nil { - peerlogger.Infoln(err) - } + err = p.ethereum.StateManager().Process(block, false) }) - /* - if !linked { - p.FetchBlocks() - } - */ + if err != nil { + peerlogger.Infoln(err) + } else { + p.FetchBlocks() + } } } } @@ -529,11 +527,10 @@ func (self *Peer) FetchHashes() { blockPool := self.ethereum.blockPool if self.td.Cmp(blockPool.td) >= 0 { - peerlogger.Debugf("Requesting hashes from %x\n", self.lastReceivedHash) blockPool.td = self.td if !blockPool.HasLatestHash() { - self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(200)})) + self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlockHashesTy, []interface{}{self.lastReceivedHash, uint32(256)})) } } } -- cgit v1.2.3