 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			166 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //go:generate go run ./generate
 | |
| 
 | |
| package kbucket
 | |
| 
 | |
| import (
 | |
| 	"container/list"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/libp2p/go-libp2p/core/peer"
 | |
| )
 | |
| 
 | |
| // PeerInfo holds all related information for a peer in the K-Bucket.
 | |
| type PeerInfo struct {
 | |
| 	Id peer.ID
 | |
| 
 | |
| 	// LastUsefulAt is the time instant at which the peer was last "useful" to us.
 | |
| 	// Please see the DHT docs for the definition of usefulness.
 | |
| 	LastUsefulAt time.Time
 | |
| 
 | |
| 	// LastSuccessfulOutboundQueryAt is the time instant at which we last got a
 | |
| 	// successful query response from the peer.
 | |
| 	LastSuccessfulOutboundQueryAt time.Time
 | |
| 
 | |
| 	// AddedAt is the time this peer was added to the routing table.
 | |
| 	AddedAt time.Time
 | |
| 
 | |
| 	// Id of the peer in the DHT XOR keyspace
 | |
| 	dhtId ID
 | |
| 
 | |
| 	// if a bucket is full, this peer can be replaced to make space for a new peer.
 | |
| 	replaceable bool
 | |
| }
 | |
| 
 | |
| // bucket holds a list of peers.
 | |
| // we synchronize on the Routing Table lock for all access to the bucket
 | |
| // and so do not need any locks in the bucket.
 | |
| // if we want/need to avoid locking the table for accessing a bucket in the future,
 | |
| // it WILL be the caller's responsibility to synchronize all access to a bucket.
 | |
| type bucket struct {
 | |
| 	list *list.List
 | |
| }
 | |
| 
 | |
| func newBucket() *bucket {
 | |
| 	b := new(bucket)
 | |
| 	b.list = list.New()
 | |
| 	return b
 | |
| }
 | |
| 
 | |
| // returns all peers in the bucket
 | |
| // it is safe for the caller to modify the returned objects as it is a defensive copy
 | |
| func (b *bucket) peers() []PeerInfo {
 | |
| 	ps := make([]PeerInfo, 0, b.len())
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		p := e.Value.(*PeerInfo)
 | |
| 		ps = append(ps, *p)
 | |
| 	}
 | |
| 	return ps
 | |
| }
 | |
| 
 | |
| // returns the "minimum" peer in the bucket based on the `lessThan` comparator passed to it.
 | |
| // It is NOT safe for the comparator to mutate the given `PeerInfo`
 | |
| // as we pass in a pointer to it.
 | |
| // It is NOT safe to modify the returned value.
 | |
| func (b *bucket) min(lessThan func(p1 *PeerInfo, p2 *PeerInfo) bool) *PeerInfo {
 | |
| 	if b.list.Len() == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	minVal := b.list.Front().Value.(*PeerInfo)
 | |
| 
 | |
| 	for e := b.list.Front().Next(); e != nil; e = e.Next() {
 | |
| 		val := e.Value.(*PeerInfo)
 | |
| 
 | |
| 		if lessThan(val, minVal) {
 | |
| 			minVal = val
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return minVal
 | |
| }
 | |
| 
 | |
| // updateAllWith updates all the peers in the bucket by applying the given update function.
 | |
| func (b *bucket) updateAllWith(updateFnc func(p *PeerInfo)) {
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		val := e.Value.(*PeerInfo)
 | |
| 		updateFnc(val)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // return the Ids of all the peers in the bucket.
 | |
| func (b *bucket) peerIds() []peer.ID {
 | |
| 	ps := make([]peer.ID, 0, b.list.Len())
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		p := e.Value.(*PeerInfo)
 | |
| 		ps = append(ps, p.Id)
 | |
| 	}
 | |
| 	return ps
 | |
| }
 | |
| 
 | |
| // returns the peer with the given Id if it exists
 | |
| // returns nil if the peerId does not exist
 | |
| func (b *bucket) getPeer(p peer.ID) *PeerInfo {
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		if e.Value.(*PeerInfo).Id == p {
 | |
| 			return e.Value.(*PeerInfo)
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // removes the peer with the given Id from the bucket.
 | |
| // returns true if successful, false otherwise.
 | |
| func (b *bucket) remove(id peer.ID) bool {
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		if e.Value.(*PeerInfo).Id == id {
 | |
| 			b.list.Remove(e)
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func (b *bucket) pushFront(p *PeerInfo) {
 | |
| 	b.list.PushFront(p)
 | |
| }
 | |
| 
 | |
| func (b *bucket) len() int {
 | |
| 	return b.list.Len()
 | |
| }
 | |
| 
 | |
| // splits a buckets peers into two buckets, the methods receiver will have
 | |
| // peers with CPL equal to cpl, the returned bucket will have peers with CPL
 | |
| // greater than cpl (returned bucket has closer peers)
 | |
| func (b *bucket) split(cpl int, target ID) *bucket {
 | |
| 	out := list.New()
 | |
| 	newbuck := newBucket()
 | |
| 	newbuck.list = out
 | |
| 	e := b.list.Front()
 | |
| 	for e != nil {
 | |
| 		pDhtId := e.Value.(*PeerInfo).dhtId
 | |
| 		peerCPL := CommonPrefixLen(pDhtId, target)
 | |
| 		if peerCPL > cpl {
 | |
| 			cur := e
 | |
| 			out.PushBack(e.Value)
 | |
| 			e = e.Next()
 | |
| 			b.list.Remove(cur)
 | |
| 			continue
 | |
| 		}
 | |
| 		e = e.Next()
 | |
| 	}
 | |
| 	return newbuck
 | |
| }
 | |
| 
 | |
| // maxCommonPrefix returns the maximum common prefix length between any peer in
 | |
| // the bucket with the target ID.
 | |
| func (b *bucket) maxCommonPrefix(target ID) uint {
 | |
| 	maxCpl := uint(0)
 | |
| 	for e := b.list.Front(); e != nil; e = e.Next() {
 | |
| 		cpl := uint(CommonPrefixLen(e.Value.(*PeerInfo).dhtId, target))
 | |
| 		if cpl > maxCpl {
 | |
| 			maxCpl = cpl
 | |
| 		}
 | |
| 	}
 | |
| 	return maxCpl
 | |
| }
 |