aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/state_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'ethchain/state_manager.go')
-rw-r--r--ethchain/state_manager.go100
1 files changed, 50 insertions, 50 deletions
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 08bd22d29..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())
}
}
@@ -217,13 +222,13 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
return err
}
- // I'm not sure, but I don't know if there should be thrown
- // any errors at this time.
- if err = sm.AccumelateRewards(state, block); err != nil {
+ if err = sm.AccumelateRewards(state, block, parent); err != nil {
statelogger.Errorln("Error accumulating reward", err)
return err
}
+ state.Update()
+
if !block.State().Cmp(state) {
err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().Trie.Root, state.Trie.Root)
return
@@ -237,6 +242,8 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// Add the block to the chain
sm.bc.Add(block)
+ sm.transState = state.Copy()
+
// Create a bloom bin for this block
filter := sm.createBloomFilter(state)
// Persist the data
@@ -305,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)
}
@@ -332,36 +341,46 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
return nil
}
-func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
- base := new(big.Int)
- for i := 0; i < uncleLength; i++ {
- base.Add(base, UncleInclusionReward)
- }
+func (sm *StateManager) AccumelateRewards(state *ethstate.State, block, parent *Block) error {
+ reward := new(big.Int).Set(BlockReward)
- return base.Add(base, BlockReward)
-}
+ knownUncles := ethutil.Set(parent.Uncles)
+ nonces := ethutil.NewSet(block.Nonce)
+ for _, uncle := range block.Uncles {
+ if nonces.Include(uncle.Nonce) {
+ // Error not unique
+ return UncleError("Uncle not unique")
+ }
-func CalculateUncleReward(block *Block) *big.Int {
- return UncleReward
-}
+ uncleParent := sm.bc.GetBlock(uncle.PrevHash)
+ if uncleParent == nil {
+ return UncleError("Uncle's parent unknown")
+ }
-func (sm *StateManager) AccumelateRewards(state *ethstate.State, block *Block) error {
- // Get the account associated with the coinbase
- account := state.GetAccount(block.Coinbase)
- // Reward amount of ether to the coinbase address
- account.AddAmount(CalculateBlockReward(block, len(block.Uncles)))
+ if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
+ return UncleError("Uncle too old")
+ }
- addr := make([]byte, len(block.Coinbase))
- copy(addr, block.Coinbase)
- state.UpdateStateObject(account)
+ if knownUncles.Include(uncle.Hash()) {
+ return UncleError("Uncle in chain")
+ }
+
+ nonces.Insert(uncle.Nonce)
+
+ r := new(big.Int)
+ r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
- for _, uncle := range block.Uncles {
uncleAccount := state.GetAccount(uncle.Coinbase)
- uncleAccount.AddAmount(CalculateUncleReward(uncle))
+ uncleAccount.AddAmount(r)
- state.UpdateStateObject(uncleAccount)
+ reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
}
+ // Get the account associated with the coinbase
+ account := state.GetAccount(block.Coinbase)
+ // Reward amount of ether to the coinbase address
+ account.AddAmount(reward)
+
return nil
}
@@ -373,14 +392,6 @@ func (sm *StateManager) Stop() {
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
bloomf := NewBloomFilter(nil)
- /*
- for addr, stateObject := range state.Manifest().ObjectChanges {
- // Set the bloom filter's bin
- bloomf.Set([]byte(addr))
-
- sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
- }
- */
for _, msg := range state.Manifest().Messages {
bloomf.Set(msg.To)
bloomf.Set(msg.From)
@@ -388,17 +399,6 @@ func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
sm.Ethereum.Reactor().Post("messages", state.Manifest().Messages)
- /*
- for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
- for addr, value := range mappedObjects {
- // Set the bloom filter's bin
- bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))
-
- sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
- }
- }
- */
-
return bloomf
}
@@ -418,7 +418,7 @@ func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message,
sm.ApplyDiff(state, parent, block)
- sm.AccumelateRewards(state, block)
+ sm.AccumelateRewards(state, block, parent)
return state.Manifest().Messages, nil
}