예제 #1
0
// newQueue creates a new download queue for scheduling block retrieval.
func newQueue() *queue {
	return &queue{
		hashPool:    make(map[common.Hash]int),
		hashQueue:   prque.New(),
		headerPool:  make(map[common.Hash]*types.Header),
		headerQueue: prque.New(),
		pendPool:    make(map[string]*fetchRequest),
		blockPool:   make(map[common.Hash]uint64),
		blockCache:  make([]*Block, blockCacheLimit),
	}
}
예제 #2
0
// New creates a block fetcher to retrieve blocks based on hash announcements.
func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher {
	return &Fetcher{
		notify:         make(chan *announce),
		inject:         make(chan *inject),
		blockFilter:    make(chan chan []*types.Block),
		headerFilter:   make(chan chan *headerFilterTask),
		bodyFilter:     make(chan chan *bodyFilterTask),
		done:           make(chan common.Hash),
		quit:           make(chan struct{}),
		announces:      make(map[string]int),
		announced:      make(map[common.Hash][]*announce),
		fetching:       make(map[common.Hash]*announce),
		fetched:        make(map[common.Hash][]*announce),
		completing:     make(map[common.Hash]*announce),
		queue:          prque.New(),
		queues:         make(map[string]int),
		queued:         make(map[common.Hash]*inject),
		getBlock:       getBlock,
		validateBlock:  validateBlock,
		broadcastBlock: broadcastBlock,
		chainHeight:    chainHeight,
		insertChain:    insertChain,
		dropPeer:       dropPeer,
	}
}
예제 #3
0
// newQueue creates a new download queue for scheduling block retrieval.
func newQueue() *queue {
	return &queue{
		hashPool:  make(map[common.Hash]int),
		hashQueue: prque.New(),
		pendPool:  make(map[string]*fetchRequest),
		blockPool: make(map[common.Hash]int),
	}
}
예제 #4
0
// NewTrieSync creates a new trie data download scheduler.
func NewTrieSync(root common.Hash, database ethdb.Database, callback TrieSyncLeafCallback) *TrieSync {
	ts := &TrieSync{
		database: database,
		requests: make(map[common.Hash]*request),
		queue:    prque.New(),
	}
	ts.AddSubTrie(root, 0, common.Hash{}, callback)
	return ts
}
예제 #5
0
// newQueue creates a new download queue for scheduling block retrieval.
func newQueue(stateDb ethdb.Database) *queue {
	return &queue{
		hashPool:         make(map[common.Hash]int),
		hashQueue:        prque.New(),
		blockTaskPool:    make(map[common.Hash]*types.Header),
		blockTaskQueue:   prque.New(),
		blockPendPool:    make(map[string]*fetchRequest),
		blockDonePool:    make(map[common.Hash]struct{}),
		receiptTaskPool:  make(map[common.Hash]*types.Header),
		receiptTaskQueue: prque.New(),
		receiptPendPool:  make(map[string]*fetchRequest),
		receiptDonePool:  make(map[common.Hash]struct{}),
		stateTaskPool:    make(map[common.Hash]int),
		stateTaskQueue:   prque.New(),
		statePendPool:    make(map[string]*fetchRequest),
		stateDatabase:    stateDb,
		resultCache:      make([]*fetchResult, blockCacheLimit),
	}
}
예제 #6
0
// newQueue creates a new download queue for scheduling block retrieval.
func newQueue(stateDb ethdb.Database) *queue {
	lock := new(sync.Mutex)
	return &queue{
		headerPendPool:   make(map[string]*fetchRequest),
		headerContCh:     make(chan bool),
		blockTaskPool:    make(map[common.Hash]*types.Header),
		blockTaskQueue:   prque.New(),
		blockPendPool:    make(map[string]*fetchRequest),
		blockDonePool:    make(map[common.Hash]struct{}),
		receiptTaskPool:  make(map[common.Hash]*types.Header),
		receiptTaskQueue: prque.New(),
		receiptPendPool:  make(map[string]*fetchRequest),
		receiptDonePool:  make(map[common.Hash]struct{}),
		stateTaskPool:    make(map[common.Hash]int),
		stateTaskQueue:   prque.New(),
		statePendPool:    make(map[string]*fetchRequest),
		stateDatabase:    stateDb,
		resultCache:      make([]*fetchResult, blockCacheLimit),
		active:           sync.NewCond(lock),
		lock:             lock,
	}
}
예제 #7
0
// Insert some data into a priority queue and pop them out in prioritized order.
func Example_usage() {
	// Define some data to push into the priority queue
	prio := []float32{77.7, 22.2, 44.4, 55.5, 11.1, 88.8, 33.3, 99.9, 0.0, 66.6}
	data := []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}

	// Create the priority queue and insert the prioritized data
	pq := prque.New()
	for i := 0; i < len(data); i++ {
		pq.Push(data[i], prio[i])
	}
	// Pop out the data and print them
	for !pq.Empty() {
		val, prio := pq.Pop()
		fmt.Printf("%.1f:%s ", prio, val)
	}
	// Output:
	// 99.9:seven 88.8:five 77.7:zero 66.6:nine 55.5:three 44.4:two 33.3:six 22.2:one 11.1:four 0.0:eight
}
예제 #8
0
// ScheduleSkeleton adds a batch of header retrieval tasks to the queue to fill
// up an already retrieved header skeleton.
func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) {
	q.lock.Lock()
	defer q.lock.Unlock()

	// No skeleton retrieval can be in progress, fail hard if so (huge implementation bug)
	if q.headerResults != nil {
		panic("skeleton assembly already in progress")
	}
	// Shedule all the header retrieval tasks for the skeleton assembly
	q.headerTaskPool = make(map[uint64]*types.Header)
	q.headerTaskQueue = prque.New()
	q.headerPeerMiss = make(map[string]map[uint64]struct{}) // Reset availability to correct invalid chains
	q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch)
	q.headerProced = 0
	q.headerOffset = from
	q.headerContCh = make(chan bool, 1)

	for i, header := range skeleton {
		index := from + uint64(i*MaxHeaderFetch)

		q.headerTaskPool[index] = header
		q.headerTaskQueue.Push(index, -float32(index))
	}
}