Merge branch 'develop' into miner

This commit is contained in:
obscuren
2015-02-11 23:46:54 +01:00
41 changed files with 1652 additions and 1098 deletions

View File

@ -8,11 +8,9 @@ import (
"time"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
@ -25,20 +23,6 @@ type PendingBlockEvent struct {
var statelogger = logger.NewLogger("BLOCK")
type EthManager interface {
BlockProcessor() *BlockProcessor
ChainManager() *ChainManager
TxPool() *TxPool
PeerCount() int
IsMining() bool
IsListening() bool
Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
ClientIdentity() p2p.ClientIdentity
Db() ethutil.Database
EventMux() *event.TypeMux
}
type BlockProcessor struct {
db ethutil.Database
// Mutex for locking the block processor. Blocks can only be handled one at a time
@ -160,6 +144,9 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
return receipts, handled, unhandled, erroneous, err
}
// Process block will attempt to process the given block's transactions and applies them
// on top of the block's parent state (given it exists) and will return wether it was
// successful or not.
func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
// Processing a blocks may never happen simultaneously
sm.mutex.Lock()
@ -175,14 +162,14 @@ func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
}
parent := sm.bc.GetBlock(header.ParentHash)
return sm.ProcessWithParent(block, parent)
return sm.processWithParent(block, parent)
}
func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, err error) {
func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big.Int, err error) {
sm.lastAttemptedBlock = block
// Create a new state based on the parent's root (e.g., create copy)
state := state.New(parent.Root(), sm.db)
//state := state.New(parent.Trie().Copy())
// Block validation
if err = sm.ValidateBlock(block, parent); err != nil {
@ -196,18 +183,23 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
header := block.Header()
// Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true.
rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, header.Bloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
// The transactions Trie's root (R = (Tr [[H1, T1], [H2, T2], ... [Hn, Tn]]))
// can be used by light clients to make sure they've received the correct Txs
txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, header.TxHash) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
return
}
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
fmt.Println("receipts", receipts)
@ -215,12 +207,14 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
return
}
// Accumulate static rewards; block reward, uncle's and uncle inclusion.
if err = sm.AccumulateRewards(state, block, parent); err != nil {
return
}
// Commit state objects/accounts to a temporary trie (does not save)
// used to calculate the state root.
state.Update(ethutil.Big0)
if !bytes.Equal(header.Root, state.Root()) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
return
@ -230,10 +224,6 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
td = CalculateTD(block, parent)
// Sync the current block's state to the database
state.Sync()
// Set the block hashes for the current messages
state.Manifest().SetHash(block.Hash())
// Reset the manifest XXX We need this?
state.Manifest().Reset()
// Remove transactions from the pool
sm.txpool.RemoveSet(block.Transactions())
@ -313,27 +303,6 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
return nil
}
func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Message, err error) {
if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash)
}
sm.lastAttemptedBlock = block
var (
parent = sm.bc.GetBlock(block.Header().ParentHash)
//state = state.New(parent.Trie().Copy())
state = state.New(parent.Root(), sm.db)
)
defer state.Reset()
sm.TransitionState(state, parent, block)
sm.AccumulateRewards(state, block, parent)
return state.Manifest().Messages, nil
}
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash)