Commit eaa2e890 authored by obscuren's avatar obscuren

PoC 6 networking code.

* Added block pool for gathering blocks from the network (chunks)
* Re wrote syncing
parent 79c64f6b
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
}
...@@ -208,6 +208,26 @@ func (bc *BlockChain) GenesisBlock() *Block { ...@@ -208,6 +208,26 @@ func (bc *BlockChain) GenesisBlock() *Block {
return bc.genesisBlock return bc.genesisBlock
} }
func (self *BlockChain) GetChainHashesFromHash(hash []byte, max uint64) (chain [][]byte) {
block := self.GetBlock(hash)
if block == nil {
return
}
// XXX Could be optimised by using a different database which only holds hashes (i.e., linked list)
for i := uint64(0); i < max; i++ {
chain = append(chain, block.Hash())
if block.Number.Cmp(ethutil.Big0) <= 0 {
break
}
block = self.GetBlock(block.PrevHash)
}
return
}
// Get chain return blocks from hash up to max in RLP format // Get chain return blocks from hash up to max in RLP format
func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} { func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} {
var chain []interface{} var chain []interface{}
......
package ethchain package ethchain
import ( import (
"math/big"
"github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"math/big"
) )
/* /*
...@@ -26,7 +27,8 @@ var GenesisHeader = []interface{}{ ...@@ -26,7 +27,8 @@ var GenesisHeader = []interface{}{
// tx sha // tx sha
"", "",
// Difficulty // Difficulty
ethutil.BigPow(2, 22), //ethutil.BigPow(2, 22),
big.NewInt(4096),
// Number // Number
ethutil.Big0, ethutil.Big0,
// Block minimum gas price // Block minimum gas price
......
...@@ -54,6 +54,8 @@ type Ethereum struct { ...@@ -54,6 +54,8 @@ type Ethereum struct {
txPool *ethchain.TxPool txPool *ethchain.TxPool
// The canonical chain // The canonical chain
blockChain *ethchain.BlockChain blockChain *ethchain.BlockChain
// The block pool
blockPool *BlockPool
// Peers (NYI) // Peers (NYI)
peers *list.List peers *list.List
// Nonce // Nonce
...@@ -116,6 +118,7 @@ func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager ...@@ -116,6 +118,7 @@ func New(db ethutil.Database, clientIdentity ethwire.ClientIdentity, keyManager
} }
ethereum.reactor = ethreact.New() ethereum.reactor = ethreact.New()
ethereum.blockPool = NewBlockPool(ethereum)
ethereum.txPool = ethchain.NewTxPool(ethereum) ethereum.txPool = ethchain.NewTxPool(ethereum)
ethereum.blockChain = ethchain.NewBlockChain(ethereum) ethereum.blockChain = ethchain.NewBlockChain(ethereum)
ethereum.stateManager = ethchain.NewStateManager(ethereum) ethereum.stateManager = ethchain.NewStateManager(ethereum)
......
...@@ -208,3 +208,11 @@ func Address(slice []byte) (addr []byte) { ...@@ -208,3 +208,11 @@ func Address(slice []byte) (addr []byte) {
return return
} }
func ByteSliceToInterface(slice [][]byte) (ret []interface{}) {
for _, i := range slice {
ret = append(ret, i)
}
return
}
...@@ -34,10 +34,15 @@ const ( ...@@ -34,10 +34,15 @@ const (
MsgGetPeersTy = 0x10 MsgGetPeersTy = 0x10
MsgPeersTy = 0x11 MsgPeersTy = 0x11
MsgTxTy = 0x12 MsgTxTy = 0x12
MsgBlockTy = 0x13
MsgGetChainTy = 0x14 MsgGetChainTy = 0x14
MsgNotInChainTy = 0x15 MsgNotInChainTy = 0x15
MsgGetTxsTy = 0x16 MsgGetTxsTy = 0x16
MsgGetBlockHashesTy = 0x17
MsgBlockHashesTy = 0x18
MsgGetBlocksTy = 0x19
MsgBlockTy = 0x13
MsgOldBlockTy = 0xbb
MsgTalkTy = 0xff MsgTalkTy = 0xff
) )
...@@ -54,6 +59,9 @@ var msgTypeToString = map[MsgType]string{ ...@@ -54,6 +59,9 @@ var msgTypeToString = map[MsgType]string{
MsgGetChainTy: "Get chain", MsgGetChainTy: "Get chain",
MsgGetTxsTy: "Get Txs", MsgGetTxsTy: "Get Txs",
MsgNotInChainTy: "Not in chain", MsgNotInChainTy: "Not in chain",
MsgGetBlockHashesTy: "Get block hashes",
MsgBlockHashesTy: "Block hashes",
MsgGetBlocksTy: "Get blocks",
} }
func (mt MsgType) String() string { func (mt MsgType) String() string {
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment