aboutsummaryrefslogtreecommitdiffstats
path: root/core/block_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/block_manager.go')
-rw-r--r--core/block_manager.go86
1 files changed, 46 insertions, 40 deletions
diff --git a/core/block_manager.go b/core/block_manager.go
index b60cecc29..c61cf6504 100644
--- a/core/block_manager.go
+++ b/core/block_manager.go
@@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
+ "gopkg.in/fatih/set.v0"
)
var statelogger = logger.NewLogger("BLOCK")
@@ -82,8 +83,8 @@ func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event
}
func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) {
- coinbase := statedb.GetOrNewStateObject(block.Coinbase)
- coinbase.SetGasPool(block.CalcGasLimit(parent))
+ coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase)
+ coinbase.SetGasPool(CalcGasLimit(parent, block))
// Process the transactions on to current block
receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false)
@@ -156,7 +157,7 @@ done:
}
block.Reward = cumulativeSum
- block.GasUsed = totalUsedGas
+ block.Header().GasUsed = totalUsedGas
return receipts, handled, unhandled, erroneous, err
}
@@ -166,14 +167,15 @@ func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Mes
sm.mutex.Lock()
defer sm.mutex.Unlock()
- if sm.bc.HasBlock(block.Hash()) {
- return nil, nil, &KnownBlockError{block.Number, block.Hash()}
+ header := block.Header()
+ if sm.bc.HasBlock(header.Hash()) {
+ return nil, nil, &KnownBlockError{header.Number, header.Hash()}
}
- if !sm.bc.HasBlock(block.PrevHash) {
- return nil, nil, ParentError(block.PrevHash)
+ if !sm.bc.HasBlock(header.ParentHash) {
+ return nil, nil, ParentError(header.ParentHash)
}
- parent := sm.bc.GetBlock(block.PrevHash)
+ parent := sm.bc.GetBlock(header.ParentHash)
return sm.ProcessWithParent(block, parent)
}
@@ -181,7 +183,7 @@ func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Mes
func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
sm.lastAttemptedBlock = block
- state := parent.State().Copy()
+ state := state.New(parent.Trie().Copy())
// Defer the Undo on the Trie. If the block processing happened
// we don't want to undo but since undo only happens on dirty
@@ -199,23 +201,23 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
return
}
+ header := block.Header()
+
rbloom := types.CreateBloom(receipts)
- if bytes.Compare(rbloom, block.LogsBloom) != 0 {
+ if bytes.Compare(rbloom, header.Bloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return
}
txSha := types.DeriveSha(block.Transactions())
- if bytes.Compare(txSha, block.TxSha) != 0 {
- err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
+ if bytes.Compare(txSha, header.TxHash) != 0 {
+ err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
return
}
receiptSha := types.DeriveSha(receipts)
- if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
- //chainlogger.Debugf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
- fmt.Printf("%x\n", ethutil.Encode(receipts))
- err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
+ if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
+ err = fmt.Errorf("validating receipt root. received=%x got=%x", header.ReceiptHash, receiptSha)
return
}
@@ -225,8 +227,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
state.Update(ethutil.Big0)
- if !block.State().Cmp(state) {
- err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
+ if !bytes.Equal(header.Root, state.Root()) {
+ err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
return
}
@@ -238,7 +240,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
messages := state.Manifest().Messages
state.Manifest().Reset()
- chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4])
+ chainlogger.Infof("Processed block #%d (%x...)\n", header.Number, block.Hash()[0:4])
sm.txpool.RemoveSet(block.Transactions())
@@ -250,14 +252,14 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I
func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
uncleDiff := new(big.Int)
- for _, uncle := range block.Uncles {
+ for _, uncle := range block.Uncles() {
uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
}
// TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
td := new(big.Int)
td = td.Add(sm.bc.Td(), uncleDiff)
- td = td.Add(td, block.Difficulty)
+ td = td.Add(td, block.Header().Difficulty)
// The new TD will only be accepted if the new difficulty is
// is greater than the previous.
@@ -273,13 +275,13 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
// Validation validates easy over difficult (dagger takes longer time = difficult)
func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
expd := CalcDifficulty(block, parent)
- if expd.Cmp(block.Difficulty) < 0 {
- return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
+ if expd.Cmp(block.Header().Difficulty) < 0 {
+ return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd)
}
- diff := block.Time - parent.Time
+ diff := block.Header().Time - parent.Header().Time
if diff < 0 {
- return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock().Time)
+ return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Header().Time, sm.bc.CurrentBlock().Header().Time)
}
/* XXX
@@ -291,7 +293,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
// Verify the nonce of the block. Return an error if it's not valid
if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) {
- return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
+ return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Header().Nonce))
}
return nil
@@ -300,24 +302,28 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent *types.Block) error {
reward := new(big.Int).Set(BlockReward)
- knownUncles := ethutil.Set(parent.Uncles)
- nonces := ethutil.NewSet(block.Nonce)
- for _, uncle := range block.Uncles {
+ knownUncles := set.New()
+ for _, uncle := range parent.Uncles() {
+ knownUncles.Add(uncle.Hash())
+ }
+
+ nonces := ethutil.NewSet(block.Header().Nonce)
+ for _, uncle := range block.Uncles() {
if nonces.Include(uncle.Nonce) {
// Error not unique
return UncleError("Uncle not unique")
}
- uncleParent := sm.bc.GetBlock(uncle.PrevHash)
+ uncleParent := sm.bc.GetBlock(uncle.ParentHash)
if uncleParent == nil {
- return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4]))
+ return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
}
- if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
+ if uncleParent.Header().Number.Cmp(new(big.Int).Sub(parent.Header().Number, big.NewInt(6))) < 0 {
return UncleError("Uncle too old")
}
- if knownUncles.Include(uncle.Hash()) {
+ if knownUncles.Has(uncle.Hash()) {
return UncleError("Uncle in chain")
}
@@ -333,15 +339,15 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
}
// Get the account associated with the coinbase
- account := statedb.GetAccount(block.Coinbase)
+ account := statedb.GetAccount(block.Header().Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(reward)
statedb.Manifest().AddMessage(&state.Message{
- To: block.Coinbase,
+ To: block.Header().Coinbase,
Input: nil,
Origin: nil,
- Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number,
+ Block: block.Hash(), Timestamp: int64(block.Header().Time), Coinbase: block.Header().Coinbase, Number: block.Header().Number,
Value: new(big.Int).Add(reward, block.Reward),
})
@@ -349,15 +355,15 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent
}
func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
- if !sm.bc.HasBlock(block.PrevHash) {
- return nil, ParentError(block.PrevHash)
+ if !sm.bc.HasBlock(block.Header().ParentHash) {
+ return nil, ParentError(block.Header().ParentHash)
}
sm.lastAttemptedBlock = block
var (
- parent = sm.bc.GetBlock(block.PrevHash)
- state = parent.State().Copy()
+ parent = sm.bc.GetBlock(block.Header().ParentHash)
+ state = state.New(parent.Trie().Copy())
)
defer state.Reset()