github.com/koko1123/flow-go-1@v0.29.6/state/protocol/util.go (about) 1 package protocol 2 3 import ( 4 "fmt" 5 6 "github.com/koko1123/flow-go-1/model/flow" 7 "github.com/koko1123/flow-go-1/model/flow/filter" 8 "github.com/koko1123/flow-go-1/module/signature" 9 ) 10 11 // IsNodeAuthorizedAt returns whether the node with the given ID is a valid 12 // un-ejected network participant as of the given state snapshot. 13 func IsNodeAuthorizedAt(snapshot Snapshot, id flow.Identifier) (bool, error) { 14 return CheckNodeStatusAt( 15 snapshot, 16 id, 17 filter.HasWeight(true), 18 filter.Not(filter.Ejected), 19 ) 20 } 21 22 // IsNodeAuthorizedWithRoleAt returns whether the node with the given ID is a valid 23 // un-ejected network participant with the specified role as of the given state snapshot. 24 // Expected errors during normal operations: 25 // - storage.ErrNotFound if snapshot references an unknown block 26 // 27 // All other errors are unexpected and potential symptoms of internal state corruption. 28 func IsNodeAuthorizedWithRoleAt(snapshot Snapshot, id flow.Identifier, role flow.Role) (bool, error) { 29 return CheckNodeStatusAt( 30 snapshot, 31 id, 32 filter.HasWeight(true), 33 filter.Not(filter.Ejected), 34 filter.HasRole(role), 35 ) 36 } 37 38 // CheckNodeStatusAt returns whether the node with the given ID is a valid identity at the given 39 // state snapshot, and satisfies all checks. 40 // Expected errors during normal operations: 41 // - storage.ErrNotFound if snapshot references an unknown block 42 // 43 // All other errors are unexpected and potential symptoms of internal state corruption. 44 func CheckNodeStatusAt(snapshot Snapshot, id flow.Identifier, checks ...flow.IdentityFilter) (bool, error) { 45 identity, err := snapshot.Identity(id) 46 if IsIdentityNotFound(err) { 47 return false, nil 48 } 49 if err != nil { 50 return false, fmt.Errorf("could not retrieve node identity (id=%x): %w)", id, err) 51 } 52 53 for _, check := range checks { 54 if !check(identity) { 55 return false, nil 56 } 57 } 58 59 return true, nil 60 } 61 62 // IsSporkRootSnapshot returns whether the given snapshot is the state snapshot 63 // representing the initial state for a spork. 64 func IsSporkRootSnapshot(snapshot Snapshot) (bool, error) { 65 segment, err := snapshot.SealingSegment() 66 if err != nil { 67 return false, fmt.Errorf("could not get snapshot head: %w", err) 68 } 69 if len(segment.Blocks) > 1 { 70 // spork root snapshots uniquely have only one block in the sealing segment 71 return false, nil 72 } 73 return true, nil 74 } 75 76 // FindGuarantors decodes the signer indices from the guarantee, and finds the guarantor identifiers from protocol state 77 // Expected Error returns during normal operations: 78 // - signature.InvalidSignerIndicesError if `signerIndices` does not encode a valid set of collection guarantors 79 // - storage.ErrNotFound if the guarantee's ReferenceBlockID is not found 80 // - protocol.ErrEpochNotCommitted if epoch has not been committed yet 81 // - protocol.ErrClusterNotFound if cluster is not found by the given chainID 82 func FindGuarantors(state State, guarantee *flow.CollectionGuarantee) ([]flow.Identifier, error) { 83 snapshot := state.AtBlockID(guarantee.ReferenceBlockID) 84 epochs := snapshot.Epochs() 85 epoch := epochs.Current() 86 cluster, err := epoch.ClusterByChainID(guarantee.ChainID) 87 88 if err != nil { 89 return nil, fmt.Errorf( 90 "fail to retrieve collector clusters for guarantee (ReferenceBlockID: %v, ChainID: %v): %w", 91 guarantee.ReferenceBlockID, guarantee.ChainID, err) 92 } 93 94 guarantorIDs, err := signature.DecodeSignerIndicesToIdentifiers(cluster.Members().NodeIDs(), guarantee.SignerIndices) 95 if err != nil { 96 return nil, fmt.Errorf("could not decode signer indices for guarantee %v: %w", guarantee.ID(), err) 97 } 98 99 return guarantorIDs, nil 100 }