aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/block_processor.go48
-rw-r--r--core/chain_manager.go41
-rw-r--r--core/helper_test.go8
-rw-r--r--core/manager.go1
-rw-r--r--core/types/block.go5
-rw-r--r--core/types/receipt.go2
6 files changed, 39 insertions, 66 deletions
diff --git a/core/block_processor.go b/core/block_processor.go
index 0eb3f8920..893c586dd 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -48,8 +48,9 @@ type BlockProcessor struct {
func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
sm := &BlockProcessor{
- db: db,
- mem: make(map[string]*big.Int),
+ db: db,
+ mem: make(map[string]*big.Int),
+ //Pow: &ethash.Ethash{},
Pow: ezp.New(),
bc: chainManager,
eventMux: eventMux,
@@ -143,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()
@@ -158,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 {
@@ -179,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)
@@ -198,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
@@ -213,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())
@@ -296,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)
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 0847980ca..c28e901c6 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -16,6 +16,11 @@ import (
var chainlogger = logger.NewLogger("CHAIN")
+type ChainEvent struct {
+ Block *types.Block
+ Td *big.Int
+}
+
type StateQuery interface {
GetAccount(addr []byte) *state.StateObject
}
@@ -73,11 +78,10 @@ type ChainManager struct {
eventMux *event.TypeMux
genesisBlock *types.Block
// Last known total difficulty
- mu sync.RWMutex
- td *big.Int
- lastBlockNumber uint64
- currentBlock *types.Block
- lastBlockHash []byte
+ mu sync.RWMutex
+ td *big.Int
+ currentBlock *types.Block
+ lastBlockHash []byte
transState *state.StateDB
}
@@ -89,13 +93,6 @@ func (self *ChainManager) Td() *big.Int {
return self.td
}
-func (self *ChainManager) LastBlockNumber() uint64 {
- self.mu.RLock()
- defer self.mu.RUnlock()
-
- return self.lastBlockNumber
-}
-
func (self *ChainManager) LastBlockHash() []byte {
self.mu.RLock()
defer self.mu.RUnlock()
@@ -144,7 +141,6 @@ func (bc *ChainManager) setLastBlock() {
rlp.Decode(bytes.NewReader(data), &block)
bc.currentBlock = &block
bc.lastBlockHash = block.Hash()
- bc.lastBlockNumber = block.Header().Number.Uint64()
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
bc.td = ethutil.BigD(bc.db.LastKnownTD())
@@ -152,7 +148,7 @@ func (bc *ChainManager) setLastBlock() {
bc.Reset()
}
- chainlogger.Infof("Last block (#%d) %x TD=%v\n", bc.lastBlockNumber, bc.currentBlock.Hash(), bc.td)
+ chainlogger.Infof("Last block (#%v) %x TD=%v\n", bc.currentBlock.Number(), bc.currentBlock.Hash(), bc.td)
}
// Block creation & chain handling
@@ -163,7 +159,7 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
var root []byte
parentHash := ZeroHash256
- if bc.CurrentBlock != nil {
+ if bc.currentBlock != nil {
root = bc.currentBlock.Header().Root
parentHash = bc.lastBlockHash
}
@@ -175,6 +171,9 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block {
ethutil.BigPow(2, 32),
nil,
"")
+ block.SetUncles(nil)
+ block.SetTransactions(nil)
+ block.SetReceipts(nil)
parent := bc.currentBlock
if parent != nil {
@@ -226,8 +225,6 @@ func (bc *ChainManager) insert(block *types.Block) {
}
func (bc *ChainManager) write(block *types.Block) {
- bc.writeBlockInfo(block)
-
encodedBlock := ethutil.Encode(block.RlpDataForStorage())
bc.db.Put(block.Hash(), encodedBlock)
}
@@ -346,11 +343,6 @@ func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) {
return td, nil
}
-// Unexported method for writing extra non-essential block info to the db
-func (bc *ChainManager) writeBlockInfo(block *types.Block) {
- bc.lastBlockNumber++
-}
-
func (bc *ChainManager) Stop() {
if bc.CurrentBlock != nil {
chainlogger.Infoln("Stopped")
@@ -384,9 +376,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
self.setTotalDifficulty(td)
self.insert(block)
- self.transState = state.New(cblock.Root(), self.db) //state.New(cblock.Trie().Copy())
- }
+ self.transState = state.New(cblock.Root(), self.db)
+ self.eventMux.Post(ChainEvent{block, td})
+ }
}
self.mu.Unlock()
diff --git a/core/helper_test.go b/core/helper_test.go
index 7b41b86f1..473576e3f 100644
--- a/core/helper_test.go
+++ b/core/helper_test.go
@@ -9,7 +9,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
)
// Implement our EthTest Manager
@@ -54,13 +53,6 @@ func (tm *TestManager) TxPool() *TxPool {
func (tm *TestManager) EventMux() *event.TypeMux {
return tm.eventMux
}
-func (tm *TestManager) Broadcast(msgType p2p.Msg, data []interface{}) {
- fmt.Println("Broadcast not implemented")
-}
-
-func (tm *TestManager) ClientIdentity() p2p.ClientIdentity {
- return nil
-}
func (tm *TestManager) KeyManager() *crypto.KeyManager {
return nil
}
diff --git a/core/manager.go b/core/manager.go
index 4671573b1..f960fc5f0 100644
--- a/core/manager.go
+++ b/core/manager.go
@@ -16,7 +16,6 @@ type EthManager interface {
IsListening() bool
Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
- ClientIdentity() p2p.ClientIdentity
Db() ethutil.Database
EventMux() *event.TypeMux
}
diff --git a/core/types/block.go b/core/types/block.go
index a334c512e..fa28f5cc7 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -6,6 +6,7 @@ import (
"math/big"
"sort"
"time"
+
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/rlp"
@@ -175,6 +176,7 @@ func (self *Block) RlpDataForStorage() interface{} {
// Header accessors (add as you need them)
func (self *Block) Number() *big.Int { return self.header.Number }
func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() }
+func (self *Block) Nonce() []byte { return self.header.Nonce }
func (self *Block) Bloom() []byte { return self.header.Bloom }
func (self *Block) Coinbase() []byte { return self.header.Coinbase }
func (self *Block) Time() int64 { return int64(self.header.Time) }
@@ -207,6 +209,7 @@ func (self *Block) ParentHash() []byte {
func (self *Block) String() string {
return fmt.Sprintf(`BLOCK(%x): Size: %v TD: %v {
+NoNonce: %x
Header:
[
%v
@@ -216,7 +219,7 @@ Transactions:
Uncles:
%v
}
-`, self.header.Hash(), self.Size(), self.Td, self.header, self.transactions, self.uncles)
+`, self.header.Hash(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles)
}
func (self *Header) String() string {
diff --git a/core/types/receipt.go b/core/types/receipt.go
index bac64e41d..49e68e233 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -17,7 +17,7 @@ type Receipt struct {
}
func NewReceipt(root []byte, cumalativeGasUsed *big.Int) *Receipt {
- return &Receipt{PostState: ethutil.CopyBytes(root), CumulativeGasUsed: cumalativeGasUsed}
+ return &Receipt{PostState: ethutil.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumalativeGasUsed)}
}
func NewRecieptFromValue(val *ethutil.Value) *Receipt {