Browse Source

cleaning up

obscuren 11 years ago
parent
commit
ca74bcc4cd
2 changed files with 136 additions and 157 deletions
  1. 5 3
      block_pool.go
  2. 131 154
      chain/chain_manager.go

+ 5 - 3
block_pool.go

@@ -333,9 +333,11 @@ out:
 					self.td = ethutil.Big0
 					self.peer = nil
 				} else {
-					chainManager.InsertChain(bchain)
-					for _, block := range blocks {
-						self.Remove(block.Hash())
+					if !chain.IsTDError(err) {
+						chainManager.InsertChain(bchain)
+						for _, block := range blocks {
+							self.Remove(block.Hash())
+						}
 					}
 				}
 			}

+ 131 - 154
chain/chain_manager.go

@@ -13,9 +13,39 @@ import (
 
 var chainlogger = logger.NewLogger("CHAIN")
 
+func AddTestNetFunds(block *Block) {
+	for _, addr := range []string{
+		"51ba59315b3a95761d0863b05ccc7a7f54703d99",
+		"e4157b34ea9615cfbde6b4fda419828124b70c78",
+		"b9c015918bdaba24b4ff057a92a3873d6eb201be",
+		"6c386a4b26f73c802f34673f7248bb118f97424a",
+		"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
+		"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
+		"e6716f9544a56c530d868e4bfbacb172315bdead",
+		"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
+	} {
+		codedAddr := ethutil.Hex2Bytes(addr)
+		account := block.state.GetAccount(codedAddr)
+		account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
+		block.state.UpdateStateObject(account)
+	}
+}
+
+func CalcDifficulty(block, parent *Block) *big.Int {
+	diff := new(big.Int)
+
+	adjust := new(big.Int).Rsh(parent.Difficulty, 10)
+	if block.Time >= parent.Time+5 {
+		diff.Sub(parent.Difficulty, adjust)
+	} else {
+		diff.Add(parent.Difficulty, adjust)
+	}
+
+	return diff
+}
+
 type ChainManager struct {
-	Ethereum EthManager
-	// The famous, the fabulous Mister GENESIIIIIIS (block)
+	eth          EthManager
 	genesisBlock *Block
 	// Last known total difficulty
 	TD *big.Int
@@ -31,17 +61,34 @@ type ChainManager struct {
 func NewChainManager(ethereum EthManager) *ChainManager {
 	bc := &ChainManager{}
 	bc.genesisBlock = NewBlockFromBytes(ethutil.Encode(Genesis))
-	bc.Ethereum = ethereum
+	bc.eth = ethereum
 
 	bc.setLastBlock()
 
 	return bc
 }
 
-func (bc *ChainManager) Genesis() *Block {
-	return bc.genesisBlock
+func (bc *ChainManager) setLastBlock() {
+	data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
+	if len(data) != 0 {
+		// Prep genesis
+		AddTestNetFunds(bc.genesisBlock)
+
+		block := NewBlockFromBytes(data)
+		bc.CurrentBlock = block
+		bc.LastBlockHash = block.Hash()
+		bc.LastBlockNumber = block.Number.Uint64()
+
+		// Set the last know difficulty (might be 0x0 as initial value, Genesis)
+		bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
+	} else {
+		bc.Reset()
+	}
+
+	chainlogger.Infof("Last block (#%d) %x\n", bc.LastBlockNumber, bc.CurrentBlock.Hash())
 }
 
+// Block creation & chain handling
 func (bc *ChainManager) NewBlock(coinbase []byte) *Block {
 	var root interface{}
 	hash := ZeroHash256
@@ -72,19 +119,6 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *Block {
 	return block
 }
 
-func CalcDifficulty(block, parent *Block) *big.Int {
-	diff := new(big.Int)
-
-	adjust := new(big.Int).Rsh(parent.Difficulty, 10)
-	if block.Time >= parent.Time+5 {
-		diff.Sub(parent.Difficulty, adjust)
-	} else {
-		diff.Add(parent.Difficulty, adjust)
-	}
-
-	return diff
-}
-
 func (bc *ChainManager) Reset() {
 	AddTestNetFunds(bc.genesisBlock)
 
@@ -99,38 +133,31 @@ func (bc *ChainManager) Reset() {
 	bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
 }
 
-func (bc *ChainManager) HasBlock(hash []byte) bool {
-	data, _ := ethutil.Config.Db.Get(hash)
-	return len(data) != 0
-}
-
-// TODO: At one point we might want to save a block by prevHash in the db to optimise this...
-func (bc *ChainManager) HasBlockWithPrevHash(hash []byte) bool {
-	block := bc.CurrentBlock
-
-	for ; block != nil; block = bc.GetBlock(block.PrevHash) {
-		if bytes.Compare(hash, block.PrevHash) == 0 {
-			return true
-		}
-	}
-	return false
-}
+// Add a block to the chain and record addition information
+func (bc *ChainManager) add(block *Block) {
+	bc.writeBlockInfo(block)
 
-func (bc *ChainManager) CalculateBlockTD(block *Block) *big.Int {
-	blockDiff := new(big.Int)
+	bc.CurrentBlock = block
+	bc.LastBlockHash = block.Hash()
 
-	for _, uncle := range block.Uncles {
-		blockDiff = blockDiff.Add(blockDiff, uncle.Difficulty)
-	}
-	blockDiff = blockDiff.Add(blockDiff, block.Difficulty)
+	encodedBlock := block.RlpEncode()
+	ethutil.Config.Db.Put(block.Hash(), encodedBlock)
+	ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
 
-	return blockDiff
+	//chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
 }
 
-func (bc *ChainManager) GenesisBlock() *Block {
+// Accessors
+func (bc *ChainManager) Genesis() *Block {
 	return bc.genesisBlock
 }
 
+// Block fetching methods
+func (bc *ChainManager) HasBlock(hash []byte) bool {
+	data, _ := ethutil.Config.Db.Get(hash)
+	return len(data) != 0
+}
+
 func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain [][]byte) {
 	block := self.GetBlock(hash)
 	if block == nil {
@@ -152,83 +179,6 @@ func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain
 	return
 }
 
-func AddTestNetFunds(block *Block) {
-	for _, addr := range []string{
-		"51ba59315b3a95761d0863b05ccc7a7f54703d99",
-		"e4157b34ea9615cfbde6b4fda419828124b70c78",
-		"b9c015918bdaba24b4ff057a92a3873d6eb201be",
-		"6c386a4b26f73c802f34673f7248bb118f97424a",
-		"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
-		"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
-		"e6716f9544a56c530d868e4bfbacb172315bdead",
-		"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
-	} {
-		codedAddr := ethutil.Hex2Bytes(addr)
-		account := block.state.GetAccount(codedAddr)
-		account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200)
-		block.state.UpdateStateObject(account)
-	}
-}
-
-func (bc *ChainManager) setLastBlock() {
-	data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
-	if len(data) != 0 {
-		// Prep genesis
-		AddTestNetFunds(bc.genesisBlock)
-
-		block := NewBlockFromBytes(data)
-		bc.CurrentBlock = block
-		bc.LastBlockHash = block.Hash()
-		bc.LastBlockNumber = block.Number.Uint64()
-
-		// Set the last know difficulty (might be 0x0 as initial value, Genesis)
-		bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD())
-	} else {
-		bc.Reset()
-	}
-
-	chainlogger.Infof("Last block (#%d) %x\n", bc.LastBlockNumber, bc.CurrentBlock.Hash())
-}
-
-func (bc *ChainManager) SetTotalDifficulty(td *big.Int) {
-	ethutil.Config.Db.Put([]byte("LTD"), td.Bytes())
-	bc.TD = td
-}
-
-// Add a block to the chain and record addition information
-func (bc *ChainManager) add(block *Block) {
-	bc.writeBlockInfo(block)
-
-	bc.CurrentBlock = block
-	bc.LastBlockHash = block.Hash()
-
-	encodedBlock := block.RlpEncode()
-	ethutil.Config.Db.Put(block.Hash(), encodedBlock)
-	ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
-
-	//chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4])
-}
-
-func (self *ChainManager) CalcTotalDiff(block *Block) (*big.Int, error) {
-	parent := self.GetBlock(block.PrevHash)
-	if parent == nil {
-		return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.PrevHash)
-	}
-
-	parentTd := parent.BlockInfo().TD
-
-	uncleDiff := new(big.Int)
-	for _, uncle := range block.Uncles {
-		uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
-	}
-
-	td := new(big.Int)
-	td = td.Add(parentTd, uncleDiff)
-	td = td.Add(td, block.Difficulty)
-
-	return td, nil
-}
-
 func (self *ChainManager) GetBlock(hash []byte) *Block {
 	data, _ := ethutil.Config.Db.Get(hash)
 	if len(data) == 0 {
@@ -262,22 +212,29 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *Block {
 	return block
 }
 
-func (self *ChainManager) GetBlockBack(num uint64) *Block {
-	block := self.CurrentBlock
+func (bc *ChainManager) SetTotalDifficulty(td *big.Int) {
+	ethutil.Config.Db.Put([]byte("LTD"), td.Bytes())
+	bc.TD = td
+}
 
-	for ; num != 0 && block != nil; num-- {
-		block = self.GetBlock(block.PrevHash)
+func (self *ChainManager) CalcTotalDiff(block *Block) (*big.Int, error) {
+	parent := self.GetBlock(block.PrevHash)
+	if parent == nil {
+		return nil, fmt.Errorf("Unable to calculate total diff without known parent %x", block.PrevHash)
 	}
 
-	return block
-}
+	parentTd := parent.BlockInfo().TD
 
-func (bc *ChainManager) BlockInfoByHash(hash []byte) BlockInfo {
-	bi := BlockInfo{}
-	data, _ := ethutil.Config.Db.Get(append(hash, []byte("Info")...))
-	bi.RlpDecode(data)
+	uncleDiff := new(big.Int)
+	for _, uncle := range block.Uncles {
+		uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
+	}
 
-	return bi
+	td := new(big.Int)
+	td = td.Add(parentTd, uncleDiff)
+	td = td.Add(td, block.Difficulty)
+
+	return td, nil
 }
 
 func (bc *ChainManager) BlockInfo(block *Block) BlockInfo {
@@ -303,24 +260,8 @@ func (bc *ChainManager) Stop() {
 	}
 }
 
-type link struct {
-	block    *Block
-	messages state.Messages
-	td       *big.Int
-}
-
-type BlockChain struct {
-	*list.List
-}
-
-func NewChain(blocks Blocks) *BlockChain {
-	chain := &BlockChain{list.New()}
-
-	for _, block := range blocks {
-		chain.PushBack(&link{block, nil, nil})
-	}
-
-	return chain
+func (self *ChainManager) NewIterator(startHash []byte) *ChainIterator {
+	return &ChainIterator{self, self.GetBlock(startHash)}
 }
 
 // This function assumes you've done your checking. No checking is done at this stage anymore
@@ -330,8 +271,8 @@ func (self *ChainManager) InsertChain(chain *BlockChain) {
 
 		self.add(link.block)
 		self.SetTotalDifficulty(link.td)
-		self.Ethereum.EventMux().Post(NewBlockEvent{link.block})
-		self.Ethereum.EventMux().Post(link.messages)
+		self.eth.EventMux().Post(NewBlockEvent{link.block})
+		self.eth.EventMux().Post(link.messages)
 	}
 
 	b, e := chain.Front(), chain.Back()
@@ -352,16 +293,13 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
 			parent = self.GetBlock(block.PrevHash)
 		)
 
-		//fmt.Println("parent", parent)
-		//fmt.Println("current", block)
-
 		if parent == nil {
 			err = fmt.Errorf("incoming chain broken on hash %x\n", block.PrevHash[0:4])
 			return
 		}
 
 		var messages state.Messages
-		td, messages, err = self.Ethereum.BlockManager().ProcessWithParent(block, parent)
+		td, messages, err = self.eth.BlockManager().ProcessWithParent(block, parent)
 		if err != nil {
 			chainlogger.Infoln(err)
 			chainlogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4])
@@ -383,3 +321,42 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
 
 	return
 }
+
+type link struct {
+	block    *Block
+	messages state.Messages
+	td       *big.Int
+}
+
+type BlockChain struct {
+	*list.List
+}
+
+func NewChain(blocks Blocks) *BlockChain {
+	chain := &BlockChain{list.New()}
+
+	for _, block := range blocks {
+		chain.PushBack(&link{block, nil, nil})
+	}
+
+	return chain
+}
+
+func (self *BlockChain) RlpEncode() []byte {
+	dat := make([]interface{}, 0)
+	for e := self.Front(); e != nil; e = e.Next() {
+		dat = append(dat, e.Value.(*link).block.RlpData())
+	}
+
+	return ethutil.Encode(dat)
+}
+
+type ChainIterator struct {
+	cm    *ChainManager
+	block *Block // current block in the iterator
+}
+
+func (self *ChainIterator) Prev() *Block {
+	self.block = self.cm.GetBlock(self.block.PrevHash)
+	return self.block
+}