github.com/Finschia/finschia-sdk@v0.48.1/x/capability/types/types.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "sort" 6 7 yaml "gopkg.in/yaml.v2" 8 9 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 10 ) 11 12 // NewCapability returns a reference to a new Capability to be used as an 13 // actual capability. 14 func NewCapability(index uint64) *Capability { 15 return &Capability{Index: index} 16 } 17 18 // String returns the string representation of a Capability. The string contains 19 // the Capability's memory reference as the string is to be used in a composite 20 // key and to authenticate capabilities. 21 func (ck *Capability) String() string { 22 return fmt.Sprintf("Capability{%p, %d}", ck, ck.Index) 23 } 24 25 func NewOwner(module, name string) Owner { 26 return Owner{Module: module, Name: name} 27 } 28 29 // Key returns a composite key for an Owner. 30 func (o Owner) Key() string { 31 return fmt.Sprintf("%s/%s", o.Module, o.Name) 32 } 33 34 func (o Owner) String() string { 35 bz, _ := yaml.Marshal(o) 36 return string(bz) 37 } 38 39 func NewCapabilityOwners() *CapabilityOwners { 40 return &CapabilityOwners{Owners: make([]Owner, 0)} 41 } 42 43 // Set attempts to add a given owner to the CapabilityOwners. If the owner 44 // already exists, an error will be returned. Set runs in O(log n) average time 45 // and O(n) in the worst case. 46 func (co *CapabilityOwners) Set(owner Owner) error { 47 i, ok := co.Get(owner) 48 if ok { 49 // owner already exists at co.Owners[i] 50 return sdkerrors.Wrapf(ErrOwnerClaimed, owner.String()) 51 } 52 53 // owner does not exist in the set of owners, so we insert at position i 54 co.Owners = append(co.Owners, Owner{}) // expand by 1 in amortized O(1) / O(n) worst case 55 copy(co.Owners[i+1:], co.Owners[i:]) 56 co.Owners[i] = owner 57 58 return nil 59 } 60 61 // Remove removes a provided owner from the CapabilityOwners if it exists. If the 62 // owner does not exist, Remove is considered a no-op. 63 func (co *CapabilityOwners) Remove(owner Owner) { 64 if len(co.Owners) == 0 { 65 return 66 } 67 68 i, ok := co.Get(owner) 69 if ok { 70 // owner exists at co.Owners[i] 71 co.Owners = append(co.Owners[:i], co.Owners[i+1:]...) 72 } 73 } 74 75 // Get returns (i, true) of the provided owner in the CapabilityOwners if the 76 // owner exists, where i indicates the owner's index in the set. Otherwise 77 // (i, false) where i indicates where in the set the owner should be added. 78 func (co *CapabilityOwners) Get(owner Owner) (int, bool) { 79 // find smallest index s.t. co.Owners[i] >= owner in O(log n) time 80 i := sort.Search(len(co.Owners), func(i int) bool { return co.Owners[i].Key() >= owner.Key() }) 81 if i < len(co.Owners) && co.Owners[i].Key() == owner.Key() { 82 // owner exists at co.Owners[i] 83 return i, true 84 } 85 86 return i, false 87 }