diff options
Diffstat (limited to 'eth/downloader')
-rw-r--r-- | eth/downloader/downloader.go | 8 | ||||
-rw-r--r-- | eth/downloader/downloader_test.go | 8 | ||||
-rw-r--r-- | eth/downloader/queue.go | 20 |
3 files changed, 22 insertions, 14 deletions
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index fd588d2f3..0634baaed 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -93,6 +93,12 @@ type Downloader struct { cancelLock sync.RWMutex // Lock to protect the cancel channel in delivers } +// Block is an origin-tagged blockchain block. +type Block struct { + RawBlock *types.Block + OriginPeer string +} + func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloader { downloader := &Downloader{ mux: mux, @@ -177,7 +183,7 @@ func (d *Downloader) Synchronise(id string, hash common.Hash) error { } // TakeBlocks takes blocks from the queue and yields them to the caller. -func (d *Downloader) TakeBlocks() types.Blocks { +func (d *Downloader) TakeBlocks() []*Block { return d.queue.TakeBlocks() } diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 8b541d8b7..66be1ca18 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -88,10 +88,10 @@ func (dl *downloadTester) sync(peerId string, head common.Hash) error { // syncTake is starts synchronising with a remote peer, but concurrently it also // starts fetching blocks that the downloader retrieved. IT blocks until both go // routines terminate. -func (dl *downloadTester) syncTake(peerId string, head common.Hash) (types.Blocks, error) { +func (dl *downloadTester) syncTake(peerId string, head common.Hash) ([]*Block, error) { // Start a block collector to take blocks as they become available done := make(chan struct{}) - took := []*types.Block{} + took := []*Block{} go func() { for running := true; running; { select { @@ -349,7 +349,7 @@ func TestNonExistingParentAttack(t *testing.T) { if len(bs) != 1 { t.Fatalf("retrieved block mismatch: have %v, want %v", len(bs), 1) } - if tester.hasBlock(bs[0].ParentHash()) { + if tester.hasBlock(bs[0].RawBlock.ParentHash()) { t.Fatalf("tester knows about the unknown hash") } tester.downloader.Cancel() @@ -364,7 +364,7 @@ func TestNonExistingParentAttack(t *testing.T) { if len(bs) != 1 { t.Fatalf("retrieved block mismatch: have %v, want %v", len(bs), 1) } - if !tester.hasBlock(bs[0].ParentHash()) { + if !tester.hasBlock(bs[0].RawBlock.ParentHash()) { t.Fatalf("tester doesn't know about the origin hash") } } diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 591a37773..7ea400dc4 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -36,7 +36,7 @@ type queue struct { pendPool map[string]*fetchRequest // Currently pending block retrieval operations blockPool map[common.Hash]int // Hash-set of the downloaded data blocks, mapping to cache indexes - blockCache []*types.Block // Downloaded but not yet delivered blocks + blockCache []*Block // Downloaded but not yet delivered blocks blockOffset int // Offset of the first cached block in the block-chain lock sync.RWMutex @@ -148,7 +148,7 @@ func (q *queue) Insert(hashes []common.Hash) []common.Hash { // GetHeadBlock retrieves the first block from the cache, or nil if it hasn't // been downloaded yet (or simply non existent). -func (q *queue) GetHeadBlock() *types.Block { +func (q *queue) GetHeadBlock() *Block { q.lock.RLock() defer q.lock.RUnlock() @@ -159,7 +159,7 @@ func (q *queue) GetHeadBlock() *types.Block { } // GetBlock retrieves a downloaded block, or nil if non-existent. -func (q *queue) GetBlock(hash common.Hash) *types.Block { +func (q *queue) GetBlock(hash common.Hash) *Block { q.lock.RLock() defer q.lock.RUnlock() @@ -176,18 +176,18 @@ func (q *queue) GetBlock(hash common.Hash) *types.Block { } // TakeBlocks retrieves and permanently removes a batch of blocks from the cache. -func (q *queue) TakeBlocks() types.Blocks { +func (q *queue) TakeBlocks() []*Block { q.lock.Lock() defer q.lock.Unlock() // Accumulate all available blocks - var blocks types.Blocks + blocks := []*Block{} for _, block := range q.blockCache { if block == nil { break } blocks = append(blocks, block) - delete(q.blockPool, block.Hash()) + delete(q.blockPool, block.RawBlock.Hash()) } // Delete the blocks from the slice and let them be garbage collected // without this slice trick the blocks would stay in memory until nil @@ -312,8 +312,10 @@ func (q *queue) Deliver(id string, blocks []*types.Block) (err error) { return ErrInvalidChain } // Otherwise merge the block and mark the hash block - q.blockCache[index] = block - + q.blockCache[index] = &Block{ + RawBlock: block, + OriginPeer: id, + } delete(request.Hashes, hash) delete(q.hashPool, hash) q.blockPool[hash] = int(block.NumberU64()) @@ -342,6 +344,6 @@ func (q *queue) Alloc(offset int) { size = blockCacheLimit } if len(q.blockCache) < size { - q.blockCache = append(q.blockCache, make([]*types.Block, size-len(q.blockCache))...) + q.blockCache = append(q.blockCache, make([]*Block, size-len(q.blockCache))...) } } |