diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/block_processor.go | 48 | ||||
-rw-r--r-- | core/chain_manager.go | 41 | ||||
-rw-r--r-- | core/helper_test.go | 8 | ||||
-rw-r--r-- | core/manager.go | 1 | ||||
-rw-r--r-- | core/types/block.go | 5 | ||||
-rw-r--r-- | core/types/receipt.go | 2 |
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: ðash.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 { |