|
|
@@ -143,6 +143,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()
|
|
|
@@ -158,14 +161,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 {
|
|
|
@@ -179,18 +182,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)
|
|
|
@@ -198,12 +206,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
|
|
|
@@ -213,10 +223,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())
|
|
|
|
|
|
@@ -296,27 +302,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)
|