aboutsummaryrefslogtreecommitdiffstats
path: root/chain/chain_manager.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-11-17 19:12:55 +0800
committerobscuren <geffobscura@gmail.com>2014-11-17 19:12:55 +0800
commitca74bcc4cdf389b5ef5520f9ab5a7aec08424f30 (patch)
tree1821adb34b5ce921ec0fb5322c02882b7e51e5c1 /chain/chain_manager.go
parent33afb10b0da43d55b1d6e1fe6b1b97c6ff8d8f75 (diff)
downloaddexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar.gz
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar.bz2
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar.lz
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar.xz
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.tar.zst
dexon-ca74bcc4cdf389b5ef5520f9ab5a7aec08424f30.zip
cleaning up
Diffstat (limited to 'chain/chain_manager.go')
-rw-r--r--chain/chain_manager.go285
1 files changed, 131 insertions, 154 deletions
diff --git a/chain/chain_manager.go b/chain/chain_manager.go
index df390a4c0..02741bc0b 100644
--- a/chain/chain_manager.go
+++ b/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
+}