Example #1
0
// Merges two leafsets and returns the result.
func (o *Overlay) mergeLeaves(a, b []*big.Int) []*big.Int {
	// Append, circular sort and fetch uniques
	res := append(a, b...)
	sort.Sort(idSlice{o.nodeId, res})
	res = res[:sortext.Unique(idSlice{o.nodeId, res})]

	// Look for the origin point
	origin := 0
	for o.nodeId.Cmp(res[origin]) != 0 {
		origin++
	}
	// Fetch the nearest nodes in both directions
	min := mathext.MaxInt(0, origin-config.PastryLeaves/2)
	max := mathext.MinInt(len(res), origin+config.PastryLeaves/2)
	return res[min:max]
}
Example #2
0
func checkRoutes(t *testing.T, nodes []*Overlay) {
	// Synchronize overlay states
	for _, o := range nodes {
		o.lock.RLock()
		defer o.lock.RUnlock()
	}
	// Extract the ids from the running nodes
	ids := make([]*big.Int, len(nodes))
	for i, o := range nodes {
		ids[i] = o.nodeId
	}
	// Assemble the leafset of each node and verify
	for _, o := range nodes {
		sort.Sort(idSlice{o.nodeId, ids})
		origin := 0
		for o.nodeId.Cmp(ids[origin]) != 0 {
			origin++
		}
		min := mathext.MaxInt(0, origin-config.PastryLeaves/2)
		max := mathext.MinInt(len(ids), origin+config.PastryLeaves/2)
		leaves := ids[min:max]

		if len(leaves) != len(o.routes.leaves) {
			t.Fatalf("overlay %v: leafset mismatch: have %v, want %v.", o.nodeId, o.routes.leaves, leaves)
		} else {
			for i, leaf := range leaves {
				if leaf.Cmp(o.routes.leaves[i]) != 0 {
					t.Fatalf("overlay %v: leafset mismatch: have %v, want %v.", o.nodeId, o.routes.leaves, leaves)
					break
				}
			}
		}
	}
	// Check the routing table for each node
	for _, o := range nodes {
		for r, row := range o.routes.routes {
			for c, p := range row {
				if p == nil {
					// Check that indeed no id is valid for this entry
					for _, id := range ids {
						if id.Cmp(o.nodeId) != 0 {
							if pre, dig := prefix(o.nodeId, id); pre == r && dig == c {
								t.Fatalf("overlay %v: entry {%v, %v} missing: %v.", o.nodeId, r, c, id)
							}
						}
					}
				} else {
					// Check that the id is valid and indeed not some leftover
					if pre, dig := prefix(o.nodeId, p); pre != r || dig != c {
						t.Fatalf("overlay %v: entry {%v, %v} invalid: %v.", o.nodeId, r, c, p)
					}
					alive := false
					for _, id := range ids {
						if id.Cmp(p) == 0 {
							alive = true
							break
						}
					}
					if !alive {
						t.Fatalf("overlay %v: entry {%v, %v} already dead: %v.", o.nodeId, r, c, p)
					}
				}
			}
		}
	}
}