diff options
author | obscuren <geffobscura@gmail.com> | 2014-08-21 20:47:58 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-08-21 20:47:58 +0800 |
commit | eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb (patch) | |
tree | 9a0c4c4b1bda39560c70147c73862d72eff38dd1 /block_pool.go | |
parent | 79c64f6bca4fcfb257496be22c64f4b2faed7050 (diff) | |
download | go-tangerine-eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb.tar.gz go-tangerine-eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb.tar.zst go-tangerine-eaa2e8900d1036e09b002c4e20fc6e4f9cd031bb.zip |
PoC 6 networking code.
* Added block pool for gathering blocks from the network (chunks)
* Re wrote syncing
Diffstat (limited to 'block_pool.go')
-rw-r--r-- | block_pool.go | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/block_pool.go b/block_pool.go new file mode 100644 index 000000000..3225bdff2 --- /dev/null +++ b/block_pool.go @@ -0,0 +1,116 @@ +package eth + +import ( + "math" + "math/big" + "sync" + + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" +) + +type block struct { + peer *Peer + block *ethchain.Block +} + +type BlockPool struct { + mut sync.Mutex + + eth *Ethereum + + hashPool [][]byte + pool map[string]*block + + td *big.Int +} + +func NewBlockPool(eth *Ethereum) *BlockPool { + return &BlockPool{ + eth: eth, + pool: make(map[string]*block), + td: ethutil.Big0, + } +} + +func (self *BlockPool) HasLatestHash() bool { + return self.pool[string(self.eth.BlockChain().CurrentBlock.Hash())] != nil +} + +func (self *BlockPool) HasCommonHash(hash []byte) bool { + return self.eth.BlockChain().GetBlock(hash) != nil +} + +func (self *BlockPool) AddHash(hash []byte) { + if self.pool[string(hash)] == nil { + self.pool[string(hash)] = &block{nil, nil} + + self.hashPool = append([][]byte{hash}, self.hashPool...) + } +} + +func (self *BlockPool) SetBlock(b *ethchain.Block) { + hash := string(b.Hash()) + + if self.pool[string(hash)] == nil { + self.pool[hash] = &block{nil, nil} + } + + self.pool[hash].block = b +} + +func (self *BlockPool) CheckLinkAndProcess(f func(block *ethchain.Block)) bool { + self.mut.Lock() + defer self.mut.Unlock() + + if self.IsLinked() { + for i, hash := range self.hashPool { + block := self.pool[string(hash)].block + if block != nil { + f(block) + + delete(self.pool, string(hash)) + } else { + self.hashPool = self.hashPool[i:] + + return false + } + } + + return true + } + + return false +} + +func (self *BlockPool) IsLinked() bool { + if len(self.hashPool) == 0 { + return false + } + + block := self.pool[string(self.hashPool[0])].block + if block != nil { + return self.eth.BlockChain().HasBlock(block.PrevHash) + } + + return false +} + +func (self *BlockPool) Take(amount int, peer *Peer) (hashes [][]byte) { + self.mut.Lock() + defer self.mut.Unlock() + + num := int(math.Min(float64(amount), float64(len(self.pool)))) + j := 0 + for i := 0; i < len(self.hashPool) && j < num; i++ { + hash := string(self.hashPool[i]) + if self.pool[hash].peer == nil || self.pool[hash].peer == peer { + self.pool[hash].peer = peer + + hashes = append(hashes, self.hashPool[i]) + j++ + } + } + + return +} |