improved blockchain downloading

This commit is contained in:
obscuren 2014-10-02 01:36:59 +02:00
parent 5fa0173c41
commit a34a971b50
2 changed files with 42 additions and 37 deletions

View File

@ -217,9 +217,7 @@ out:
} }
}) })
if !self.fetchingHashes && len(self.hashPool) > 0 { self.DistributeHashes()
self.DistributeHashes()
}
if self.ChainLength < len(self.hashPool) { if self.ChainLength < len(self.hashPool) {
self.ChainLength = len(self.hashPool) self.ChainLength = len(self.hashPool)

75
peer.go
View File

@ -129,9 +129,9 @@ type Peer struct {
statusKnown bool statusKnown bool
// Last received pong message // Last received pong message
lastPong int64 lastPong int64
lastBlockReceived time.Time lastBlockReceived time.Time
LastHashReceived time.Time doneFetchingHashes bool
host []byte host []byte
port uint16 port uint16
@ -164,36 +164,38 @@ func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
pubkey := ethereum.KeyManager().PublicKey()[1:] pubkey := ethereum.KeyManager().PublicKey()[1:]
return &Peer{ return &Peer{
outputQueue: make(chan *ethwire.Msg, outputBufferSize), outputQueue: make(chan *ethwire.Msg, outputBufferSize),
quit: make(chan bool), quit: make(chan bool),
ethereum: ethereum, ethereum: ethereum,
conn: conn, conn: conn,
inbound: inbound, inbound: inbound,
disconnect: 0, disconnect: 0,
connected: 1, connected: 1,
port: 30303, port: 30303,
pubkey: pubkey, pubkey: pubkey,
blocksRequested: 10, blocksRequested: 10,
caps: ethereum.ServerCaps(), caps: ethereum.ServerCaps(),
version: ethereum.ClientIdentity().String(), version: ethereum.ClientIdentity().String(),
protocolCaps: ethutil.NewValue(nil), protocolCaps: ethutil.NewValue(nil),
td: big.NewInt(0), td: big.NewInt(0),
doneFetchingHashes: true,
} }
} }
func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
p := &Peer{ p := &Peer{
outputQueue: make(chan *ethwire.Msg, outputBufferSize), outputQueue: make(chan *ethwire.Msg, outputBufferSize),
quit: make(chan bool), quit: make(chan bool),
ethereum: ethereum, ethereum: ethereum,
inbound: false, inbound: false,
connected: 0, connected: 0,
disconnect: 0, disconnect: 0,
port: 30303, port: 30303,
caps: caps, caps: caps,
version: ethereum.ClientIdentity().String(), version: ethereum.ClientIdentity().String(),
protocolCaps: ethutil.NewValue(nil), protocolCaps: ethutil.NewValue(nil),
td: big.NewInt(0), td: big.NewInt(0),
doneFetchingHashes: true,
} }
// Set up the connection in another goroutine so we don't block the main thread // Set up the connection in another goroutine so we don't block the main thread
@ -503,20 +505,22 @@ func (p *Peer) HandleInbound() {
it := msg.Data.NewIterator() it := msg.Data.NewIterator()
for it.Next() { for it.Next() {
hash := it.Value().Bytes() hash := it.Value().Bytes()
p.lastReceivedHash = hash
if blockPool.HasCommonHash(hash) { if blockPool.HasCommonHash(hash) {
foundCommonHash = true foundCommonHash = true
break break
} }
p.lastReceivedHash = hash
p.LastHashReceived = time.Now()
blockPool.AddHash(hash, p) blockPool.AddHash(hash, p)
} }
if !foundCommonHash && msg.Data.Len() != 0 { if !foundCommonHash && msg.Data.Len() != 0 {
p.FetchHashes() p.FetchHashes()
} else {
peerlogger.Infof("Found common hash (%x...)\n", p.lastReceivedHash[0:4])
p.doneFetchingHashes = true
} }
case ethwire.MsgBlockTy: case ethwire.MsgBlockTy:
@ -543,11 +547,15 @@ func (p *Peer) HandleInbound() {
func (self *Peer) FetchBlocks(hashes [][]byte) { func (self *Peer) FetchBlocks(hashes [][]byte) {
if len(hashes) > 0 { if len(hashes) > 0 {
peerlogger.Debugf("Fetching blocks (%d)\n", len(hashes))
self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes))) self.QueueMessage(ethwire.NewMessage(ethwire.MsgGetBlocksTy, ethutil.ByteSliceToInterface(hashes)))
} }
} }
func (self *Peer) FetchHashes() { func (self *Peer) FetchHashes() {
self.doneFetchingHashes = false
blockPool := self.ethereum.blockPool blockPool := self.ethereum.blockPool
if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 { if self.td.Cmp(self.ethereum.HighestTDPeer()) >= 0 {
@ -562,7 +570,7 @@ func (self *Peer) FetchHashes() {
} }
func (self *Peer) FetchingHashes() bool { func (self *Peer) FetchingHashes() bool {
return time.Since(self.LastHashReceived) < 200*time.Millisecond return !self.doneFetchingHashes
} }
// General update method // General update method
@ -576,10 +584,9 @@ out:
if self.IsCap("eth") { if self.IsCap("eth") {
var ( var (
sinceBlock = time.Since(self.lastBlockReceived) sinceBlock = time.Since(self.lastBlockReceived)
sinceHash = time.Since(self.LastHashReceived)
) )
if sinceBlock > 5*time.Second && sinceHash > 5*time.Second { if sinceBlock > 5*time.Second {
self.catchingUp = false self.catchingUp = false
} }
} }