Fixed issue in VM where LOG didn't pop anything of the stack

This commit is contained in:
obscuren 2014-12-05 12:32:47 +01:00
parent 3cf0477c21
commit d80f8bda94
6 changed files with 56 additions and 48 deletions

View File

@ -99,11 +99,7 @@ func (self *BlockPool) FetchHashes(peer *Peer) bool {
self.td = peer.td self.td = peer.td
if !self.HasLatestHash() { if !self.HasLatestHash() {
peer.doneFetchingHashes = false self.fetchHashes()
const amount = 256
peerlogger.Debugf("Fetching hashes (%d) %x...\n", amount, peer.lastReceivedHash[0:4])
peer.QueueMessage(wire.NewMessage(wire.MsgGetBlockHashesTy, []interface{}{peer.lastReceivedHash, uint32(amount)}))
} }
return true return true
@ -112,6 +108,16 @@ func (self *BlockPool) FetchHashes(peer *Peer) bool {
return false return false
} }
func (self *BlockPool) fetchHashes() {
peer := self.peer
peer.doneFetchingHashes = false
const amount = 256
peerlogger.Debugf("Fetching hashes (%d) %x...\n", amount, peer.lastReceivedHash[0:4])
peer.QueueMessage(wire.NewMessage(wire.MsgGetBlockHashesTy, []interface{}{peer.lastReceivedHash, uint32(amount)}))
}
func (self *BlockPool) AddHash(hash []byte, peer *Peer) { func (self *BlockPool) AddHash(hash []byte, peer *Peer) {
self.mut.Lock() self.mut.Lock()
defer self.mut.Unlock() defer self.mut.Unlock()
@ -259,6 +265,13 @@ out:
self.ChainLength = len(self.hashes) self.ChainLength = len(self.hashes)
} }
if self.peer != nil &&
!self.peer.doneFetchingHashes &&
time.Since(self.peer.lastHashAt) > 10*time.Second &&
time.Since(self.peer.lastHashRequestedAt) > 5*time.Second {
self.fetchHashes()
}
/* /*
if !self.fetchingHashes { if !self.fetchingHashes {
blocks := self.Blocks() blocks := self.Blocks()

View File

@ -236,6 +236,12 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
return return
} }
rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, block.LogsBloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
txSha := types.DeriveSha(block.Transactions()) txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, block.TxSha) != 0 { if bytes.Compare(txSha, block.TxSha) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha) err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
@ -252,13 +258,6 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
return return
} }
//block.receipts = receipts // although this isn't necessary it be in the future
rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, block.LogsBloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
state.Update(ethutil.Big0) state.Update(ethutil.Big0)
if !block.State().Cmp(state) { if !block.State().Cmp(state) {

View File

@ -20,18 +20,16 @@ func CreateBloom(receipts Receipts) []byte {
func LogsBloom(logs state.Logs) *big.Int { func LogsBloom(logs state.Logs) *big.Int {
bin := new(big.Int) bin := new(big.Int)
for _, log := range logs { for _, log := range logs {
data := [][]byte{log.Address()} data := make([][]byte, len(log.Topics())+1)
for _, topic := range log.Topics() { data[0] = log.Address()
data = append(data, topic)
for i, topic := range log.Topics() {
data[i+1] = topic
} }
for _, b := range data { for _, b := range data {
bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes())) bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes()))
} }
//if log.Data != nil {
// data = append(data, log.Data)
//}
} }
return bin return bin

View File

@ -64,5 +64,18 @@ func (self *Receipt) String() string {
type Receipts []*Receipt type Receipts []*Receipt
func (self Receipts) RlpData() interface{} {
data := make([]interface{}, len(self))
for i, receipt := range self {
data[i] = receipt.RlpData()
}
return data
}
func (self Receipts) RlpEncode() []byte {
return ethutil.Encode(self.RlpData())
}
func (self Receipts) Len() int { return len(self) } func (self Receipts) Len() int { return len(self) }
func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) } func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) }

33
peer.go
View File

@ -24,7 +24,7 @@ const (
// The size of the output buffer for writing messages // The size of the output buffer for writing messages
outputBufferSize = 50 outputBufferSize = 50
// Current protocol version // Current protocol version
ProtocolVersion = 47 ProtocolVersion = 48
// Current P2P version // Current P2P version
P2PVersion = 2 P2PVersion = 2
// Ethereum network version // Ethereum network version
@ -132,6 +132,8 @@ type Peer struct {
lastPong int64 lastPong int64
lastBlockReceived time.Time lastBlockReceived time.Time
doneFetchingHashes bool doneFetchingHashes bool
lastHashAt time.Time
lastHashRequestedAt time.Time
host []byte host []byte
port uint16 port uint16
@ -327,19 +329,16 @@ out:
} }
} }
switch msg.Type {
case wire.MsgGetBlockHashesTy:
p.lastHashRequestedAt = time.Now()
}
p.writeMessage(msg) p.writeMessage(msg)
p.lastSend = time.Now() p.lastSend = time.Now()
// Ping timer // Ping timer
case <-pingTimer.C: case <-pingTimer.C:
/*
timeSince := time.Since(time.Unix(p.lastPong, 0))
if !p.pingStartTime.IsZero() && p.lastPong != 0 && timeSince > (pingPongTimer+30*time.Second) {
peerlogger.Infof("Peer did not respond to latest pong fast enough, it took %s, disconnecting.\n", timeSince)
p.Stop()
return
}
*/
p.writeMessage(wire.NewMessage(wire.MsgPingTy, "")) p.writeMessage(wire.NewMessage(wire.MsgPingTy, ""))
p.pingStartTime = time.Now() p.pingStartTime = time.Now()
@ -462,18 +461,6 @@ func (p *Peer) HandleInbound() {
// TMP // TMP
if p.statusKnown { if p.statusKnown {
switch msg.Type { switch msg.Type {
/*
case wire.MsgGetTxsTy:
// Get the current transactions of the pool
txs := p.ethereum.TxPool().CurrentTransactions()
// Get the RlpData values from the txs
txsInterface := make([]interface{}, len(txs))
for i, tx := range txs {
txsInterface[i] = tx.RlpData()
}
// Broadcast it back to the peer
p.QueueMessage(wire.NewMessage(wire.MsgTxTy, txsInterface))
*/
case wire.MsgGetBlockHashesTy: case wire.MsgGetBlockHashesTy:
if msg.Data.Len() < 2 { if msg.Data.Len() < 2 {
@ -508,6 +495,7 @@ func (p *Peer) HandleInbound() {
blockPool := p.ethereum.blockPool blockPool := p.ethereum.blockPool
foundCommonHash := false foundCommonHash := false
p.lastHashAt = time.Now()
it := msg.Data.NewIterator() it := msg.Data.NewIterator()
for it.Next() { for it.Next() {
@ -524,9 +512,6 @@ func (p *Peer) HandleInbound() {
} }
if !foundCommonHash { if !foundCommonHash {
//if !p.FetchHashes() {
// p.doneFetchingHashes = true
//}
p.FetchHashes() p.FetchHashes()
} else { } else {
peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4]) peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4])

View File

@ -744,12 +744,12 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *
case LOG0, LOG1, LOG2, LOG3, LOG4: case LOG0, LOG1, LOG2, LOG3, LOG4:
n := int(op - LOG0) n := int(op - LOG0)
topics := make([][]byte, n) topics := make([][]byte, n)
mSize, mStart := stack.Pop().Int64(), stack.Pop().Int64() mSize, mStart := stack.Popn()
data := mem.Geti(mStart, mSize)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
topics[i] = ethutil.LeftPadBytes(stack.Pop().Bytes(), 32) topics[i] = ethutil.LeftPadBytes(stack.Pop().Bytes(), 32)
} }
data := mem.Geti(mStart.Int64(), mSize.Int64())
log := &Log{closure.Address(), topics, data} log := &Log{closure.Address(), topics, data}
self.env.AddLog(log) self.env.AddLog(log)