github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/convert/service_event.go (about)

     1  package convert
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  
     7  	"github.com/coreos/go-semver/semver"
     8  	"github.com/onflow/cadence"
     9  	"github.com/onflow/cadence/encoding/ccf"
    10  	"github.com/onflow/crypto"
    11  
    12  	"github.com/onflow/flow-go/fvm/systemcontracts"
    13  	"github.com/onflow/flow-go/model/flow"
    14  )
    15  
    16  // ServiceEvent converts a service event encoded as the generic flow.Event
    17  // type to a flow.ServiceEvent type for use within protocol software and protocol
    18  // state. This acts as the conversion from the Cadence type to the flow-go type.
    19  // CAUTION: This function must only be used for input events computed locally, by an
    20  // Execution or Verification Node; it is not resilient to malicious inputs.
    21  // No errors are expected during normal operation.
    22  func ServiceEvent(chainID flow.ChainID, event flow.Event) (*flow.ServiceEvent, error) {
    23  	events := systemcontracts.ServiceEventsForChain(chainID)
    24  
    25  	// depending on type of service event construct Go type
    26  	switch event.Type {
    27  	case events.EpochSetup.EventType():
    28  		return convertServiceEventEpochSetup(event)
    29  	case events.EpochCommit.EventType():
    30  		return convertServiceEventEpochCommit(event)
    31  	case events.VersionBeacon.EventType():
    32  		return convertServiceEventVersionBeacon(event)
    33  	case events.ProtocolStateVersionUpgrade.EventType():
    34  		return convertServiceEventProtocolStateVersionUpgrade(event)
    35  	default:
    36  		return nil, fmt.Errorf("invalid event type: %s", event.Type)
    37  	}
    38  }
    39  
    40  func getField[T cadence.Value](fields map[string]cadence.Value, fieldName string) (T, error) {
    41  	field, ok := fields[fieldName]
    42  	if !ok || field == nil {
    43  		var zero T
    44  		return zero, fmt.Errorf(
    45  			"required field not found: %s",
    46  			fieldName,
    47  		)
    48  	}
    49  
    50  	value, ok := field.(T)
    51  	if !ok {
    52  		var zero T
    53  		return zero, invalidCadenceTypeError(fieldName, field, zero)
    54  	}
    55  
    56  	return value, nil
    57  }
    58  
    59  // convertServiceEventEpochSetup converts a service event encoded as the generic
    60  // flow.Event type to a ServiceEvent type for an EpochSetup event
    61  // CONVENTION: in the returned `EpochSetup` event,
    62  //   - Node identities listed in `EpochSetup.Participants` are in CANONICAL ORDER
    63  //   - for each cluster assignment (i.e. element in `EpochSetup.Assignments`), the nodeIDs are listed in CANONICAL ORDER
    64  //
    65  // CAUTION: This function must only be used for input events computed locally, by an
    66  // Execution or Verification Node; it is not resilient to malicious inputs.
    67  // No errors are expected during normal operation.
    68  func convertServiceEventEpochSetup(event flow.Event) (*flow.ServiceEvent, error) {
    69  	// decode bytes using ccf
    70  	payload, err := ccf.Decode(nil, event.Payload)
    71  	if err != nil {
    72  		return nil, fmt.Errorf("could not unmarshal event payload: %w", err)
    73  	}
    74  
    75  	// NOTE: variable names prefixed with cdc represent cadence types
    76  	cdcEvent, ok := payload.(cadence.Event)
    77  	if !ok {
    78  		return nil, invalidCadenceTypeError("payload", payload, cadence.Event{})
    79  	}
    80  
    81  	if cdcEvent.Type() == nil {
    82  		return nil, fmt.Errorf("EpochSetup event doesn't have type")
    83  	}
    84  
    85  	fields := cadence.FieldsMappedByName(cdcEvent)
    86  
    87  	const expectedFieldCount = 11
    88  	if len(fields) < expectedFieldCount {
    89  		return nil, fmt.Errorf(
    90  			"insufficient fields in EpochSetup event (%d < %d)",
    91  			len(fields),
    92  			expectedFieldCount,
    93  		)
    94  	}
    95  
    96  	// parse EpochSetup event
    97  
    98  	counter, err := getField[cadence.UInt64](fields, "counter")
    99  	if err != nil {
   100  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   101  	}
   102  
   103  	cdcParticipants, err := getField[cadence.Array](fields, "nodeInfo")
   104  	if err != nil {
   105  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   106  	}
   107  
   108  	firstView, err := getField[cadence.UInt64](fields, "firstView")
   109  	if err != nil {
   110  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   111  	}
   112  
   113  	finalView, err := getField[cadence.UInt64](fields, "finalView")
   114  	if err != nil {
   115  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   116  	}
   117  
   118  	cdcClusters, err := getField[cadence.Array](fields, "collectorClusters")
   119  	if err != nil {
   120  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   121  	}
   122  
   123  	randomSrcHex, err := getField[cadence.String](fields, "randomSource")
   124  	if err != nil {
   125  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   126  	}
   127  
   128  	targetDuration, err := getField[cadence.UInt64](fields, "targetDuration") // Epoch duration [seconds]
   129  	if err != nil {
   130  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   131  	}
   132  
   133  	targetEndTimeUnix, err := getField[cadence.UInt64](fields, "targetEndTime") // Unix time [seconds]
   134  	if err != nil {
   135  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   136  	}
   137  
   138  	dkgPhase1FinalView, err := getField[cadence.UInt64](fields, "DKGPhase1FinalView")
   139  	if err != nil {
   140  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   141  	}
   142  
   143  	dkgPhase2FinalView, err := getField[cadence.UInt64](fields, "DKGPhase2FinalView")
   144  	if err != nil {
   145  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   146  	}
   147  
   148  	dkgPhase3FinalView, err := getField[cadence.UInt64](fields, "DKGPhase3FinalView")
   149  	if err != nil {
   150  		return nil, fmt.Errorf("failed to decode EpochSetup event: %w", err)
   151  	}
   152  
   153  	setup := &flow.EpochSetup{
   154  		Counter:            uint64(counter),
   155  		FirstView:          uint64(firstView),
   156  		FinalView:          uint64(finalView),
   157  		DKGPhase1FinalView: uint64(dkgPhase1FinalView),
   158  		DKGPhase2FinalView: uint64(dkgPhase2FinalView),
   159  		DKGPhase3FinalView: uint64(dkgPhase3FinalView),
   160  		TargetDuration:     uint64(targetDuration),
   161  		TargetEndTime:      uint64(targetEndTimeUnix),
   162  	}
   163  
   164  	// random source from the event must be a hex string
   165  	// containing exactly 128 bits (equivalent to 16 bytes or 32 hex characters)
   166  	setup.RandomSource, err = hex.DecodeString(string(randomSrcHex))
   167  	if err != nil {
   168  		return nil, fmt.Errorf(
   169  			"could not decode random source hex (%v): %w",
   170  			randomSrcHex,
   171  			err,
   172  		)
   173  	}
   174  
   175  	if len(setup.RandomSource) != flow.EpochSetupRandomSourceLength {
   176  		return nil, fmt.Errorf(
   177  			"random source in epoch setup event must be of (%d) bytes, got (%d)",
   178  			flow.EpochSetupRandomSourceLength,
   179  			len(setup.RandomSource),
   180  		)
   181  	}
   182  
   183  	// parse cluster assignments; returned assignments are in canonical order
   184  	setup.Assignments, err = convertClusterAssignments(cdcClusters.Values)
   185  	if err != nil {
   186  		return nil, fmt.Errorf("could not convert cluster assignments: %w", err)
   187  	}
   188  
   189  	// parse epoch participants; returned node identities are in canonical order
   190  	setup.Participants, err = convertParticipants(cdcParticipants.Values)
   191  	if err != nil {
   192  		return nil, fmt.Errorf("could not convert participants: %w", err)
   193  	}
   194  
   195  	// construct the service event
   196  	serviceEvent := &flow.ServiceEvent{
   197  		Type:  flow.ServiceEventSetup,
   198  		Event: setup,
   199  	}
   200  
   201  	return serviceEvent, nil
   202  }
   203  
   204  // convertServiceEventEpochCommit converts a service event encoded as the generic
   205  // flow.Event type to a ServiceEvent type for an EpochCommit event.
   206  // CAUTION: This function must only be used for input events computed locally, by an
   207  // Execution or Verification Node; it is not resilient to malicious inputs.
   208  // No errors are expected during normal operation.
   209  func convertServiceEventEpochCommit(event flow.Event) (*flow.ServiceEvent, error) {
   210  	// decode bytes using ccf
   211  	payload, err := ccf.Decode(nil, event.Payload)
   212  	if err != nil {
   213  		return nil, fmt.Errorf("could not unmarshal event payload: %w", err)
   214  	}
   215  
   216  	cdcEvent, ok := payload.(cadence.Event)
   217  	if !ok {
   218  		return nil, invalidCadenceTypeError("payload", payload, cadence.Event{})
   219  	}
   220  
   221  	if cdcEvent.Type() == nil {
   222  		return nil, fmt.Errorf("EpochCommit event doesn't have type")
   223  	}
   224  
   225  	fields := cadence.FieldsMappedByName(cdcEvent)
   226  
   227  	const expectedFieldCount = 3
   228  	if len(fields) < expectedFieldCount {
   229  		return nil, fmt.Errorf(
   230  			"insufficient fields in EpochCommit event (%d < %d)",
   231  			len(fields),
   232  			expectedFieldCount,
   233  		)
   234  	}
   235  
   236  	// Extract EpochCommit event fields
   237  
   238  	counter, err := getField[cadence.UInt64](fields, "counter")
   239  	if err != nil {
   240  		return nil, fmt.Errorf("failed to decode EpochCommit event: %w", err)
   241  	}
   242  
   243  	cdcClusterQCVotes, err := getField[cadence.Array](fields, "clusterQCs")
   244  	if err != nil {
   245  		return nil, fmt.Errorf("failed to decode EpochCommit event: %w", err)
   246  	}
   247  
   248  	cdcDKGKeys, err := getField[cadence.Array](fields, "dkgPubKeys")
   249  	if err != nil {
   250  		return nil, fmt.Errorf("failed to decode EpochCommit event: %w", err)
   251  	}
   252  
   253  	commit := &flow.EpochCommit{
   254  		Counter: uint64(counter),
   255  	}
   256  
   257  	// parse cluster qc votes
   258  	commit.ClusterQCs, err = convertClusterQCVotes(cdcClusterQCVotes.Values)
   259  	if err != nil {
   260  		return nil, fmt.Errorf("could not convert cluster qc votes: %w", err)
   261  	}
   262  
   263  	// parse DKG group key and participants
   264  	// Note: this is read in the same order as `DKGClient.SubmitResult` ie. with the group public key first followed by individual keys
   265  	// https://github.com/onflow/flow-go/blob/feature/dkg/module/dkg/client.go#L182-L183
   266  	dkgGroupKey, dkgParticipantKeys, err := convertDKGKeys(cdcDKGKeys.Values)
   267  	if err != nil {
   268  		return nil, fmt.Errorf("could not convert DKG keys: %w", err)
   269  	}
   270  	commit.DKGGroupKey = dkgGroupKey
   271  	commit.DKGParticipantKeys = dkgParticipantKeys
   272  
   273  	// create the service event
   274  	serviceEvent := &flow.ServiceEvent{
   275  		Type:  flow.ServiceEventCommit,
   276  		Event: commit,
   277  	}
   278  
   279  	return serviceEvent, nil
   280  }
   281  
   282  // convertClusterAssignments converts the Cadence representation of cluster
   283  // assignments included in the EpochSetup into the protocol AssignmentList
   284  // representation.
   285  // CONVENTION: for each cluster assignment (i.e. element in `AssignmentList`), the nodeIDs are listed in CANONICAL ORDER
   286  func convertClusterAssignments(cdcClusters []cadence.Value) (flow.AssignmentList, error) {
   287  	// ensure we don't have duplicate cluster indices
   288  	indices := make(map[uint]struct{})
   289  
   290  	// parse cluster assignments to Go types
   291  	clusterAssignments := make([]flow.IdentifierList, len(cdcClusters))
   292  	for _, value := range cdcClusters {
   293  		cdcCluster, ok := value.(cadence.Struct)
   294  		if !ok {
   295  			return nil, invalidCadenceTypeError("cluster", cdcCluster, cadence.Struct{})
   296  		}
   297  
   298  		if cdcCluster.Type() == nil {
   299  			return nil, fmt.Errorf("cluster struct doesn't have type")
   300  		}
   301  
   302  		fields := cadence.FieldsMappedByName(cdcCluster)
   303  
   304  		const expectedFieldCount = 2
   305  		if len(fields) < expectedFieldCount {
   306  			return nil, fmt.Errorf(
   307  				"insufficient fields (%d < %d)",
   308  				len(fields),
   309  				expectedFieldCount,
   310  			)
   311  		}
   312  
   313  		// Extract cluster fields
   314  
   315  		clusterIndex, err := getField[cadence.UInt16](fields, "index")
   316  		if err != nil {
   317  			return nil, fmt.Errorf("failed to decode cluster struct: %w", err)
   318  		}
   319  		// ensure cluster index is valid
   320  		if int(clusterIndex) >= len(cdcClusters) {
   321  			return nil, fmt.Errorf(
   322  				"invalid cdcCluster index (%d) outside range [0,%d]",
   323  				clusterIndex,
   324  				len(cdcClusters)-1,
   325  			)
   326  		}
   327  		_, dup := indices[uint(clusterIndex)]
   328  		if dup {
   329  			return nil, fmt.Errorf("duplicate cdcCluster index (%d)", clusterIndex)
   330  		}
   331  
   332  		weightsByNodeID, err := getField[cadence.Dictionary](fields, "nodeWeights")
   333  		if err != nil {
   334  			return nil, fmt.Errorf("failed to decode cluster struct: %w", err)
   335  		}
   336  
   337  		// read weights to retrieve node IDs of cdcCluster members
   338  		clusterMembers := make(flow.IdentifierList, 0, len(weightsByNodeID.Pairs))
   339  		for _, pair := range weightsByNodeID.Pairs {
   340  			nodeIDString, ok := pair.Key.(cadence.String)
   341  			if !ok {
   342  				return nil, invalidCadenceTypeError(
   343  					"clusterWeights.nodeID",
   344  					pair.Key,
   345  					cadence.String(""),
   346  				)
   347  			}
   348  			nodeID, err := flow.HexStringToIdentifier(string(nodeIDString))
   349  			if err != nil {
   350  				return nil, fmt.Errorf(
   351  					"could not convert hex string to identifer: %w",
   352  					err,
   353  				)
   354  			}
   355  			clusterMembers = append(clusterMembers, nodeID)
   356  		}
   357  
   358  		// IMPORTANT: for each cluster, node IDs must be in *canonical order*
   359  		clusterAssignments[clusterIndex] = clusterMembers.Sort(flow.IdentifierCanonical)
   360  	}
   361  
   362  	return clusterAssignments, nil
   363  }
   364  
   365  // convertParticipants converts the network participants specified in the
   366  // EpochSetup event into an IdentityList.
   367  // CONVENTION: returned IdentityList is in CANONICAL ORDER
   368  func convertParticipants(cdcParticipants []cadence.Value) (flow.IdentitySkeletonList, error) {
   369  	participants := make(flow.IdentitySkeletonList, 0, len(cdcParticipants))
   370  
   371  	for _, value := range cdcParticipants {
   372  		// checking compliance with expected format
   373  		cdcNodeInfoStruct, ok := value.(cadence.Struct)
   374  		if !ok {
   375  			return nil, invalidCadenceTypeError(
   376  				"cdcNodeInfoFields",
   377  				value,
   378  				cadence.Struct{},
   379  			)
   380  		}
   381  
   382  		if cdcNodeInfoStruct.Type() == nil {
   383  			return nil, fmt.Errorf("nodeInfo struct doesn't have type")
   384  		}
   385  
   386  		fields := cadence.FieldsMappedByName(cdcNodeInfoStruct)
   387  
   388  		const expectedFieldCount = 14
   389  		if len(fields) < expectedFieldCount {
   390  			return nil, fmt.Errorf(
   391  				"insufficient fields (%d < %d)",
   392  				len(fields),
   393  				expectedFieldCount,
   394  			)
   395  		}
   396  
   397  		nodeIDHex, err := getField[cadence.String](fields, "id")
   398  		if err != nil {
   399  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   400  		}
   401  
   402  		role, err := getField[cadence.UInt8](fields, "role")
   403  		if err != nil {
   404  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   405  		}
   406  		if !flow.Role(role).Valid() {
   407  			return nil, fmt.Errorf("invalid role %d", role)
   408  		}
   409  
   410  		address, err := getField[cadence.String](fields, "networkingAddress")
   411  		if err != nil {
   412  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   413  		}
   414  
   415  		networkKeyHex, err := getField[cadence.String](fields, "networkingKey")
   416  		if err != nil {
   417  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   418  		}
   419  
   420  		stakingKeyHex, err := getField[cadence.String](fields, "stakingKey")
   421  		if err != nil {
   422  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   423  		}
   424  
   425  		initialWeight, err := getField[cadence.UInt64](fields, "initialWeight")
   426  		if err != nil {
   427  			return nil, fmt.Errorf("failed to decode nodeInfo struct: %w", err)
   428  		}
   429  
   430  		identity := &flow.IdentitySkeleton{
   431  			InitialWeight: uint64(initialWeight),
   432  			Address:       string(address),
   433  			Role:          flow.Role(role),
   434  		}
   435  
   436  		// convert nodeID string into identifier
   437  		identity.NodeID, err = flow.HexStringToIdentifier(string(nodeIDHex))
   438  		if err != nil {
   439  			return nil, fmt.Errorf("could not convert hex string to identifer: %w", err)
   440  		}
   441  
   442  		// parse to PublicKey the networking key hex string
   443  		networkKeyBytes, err := hex.DecodeString(string(networkKeyHex))
   444  		if err != nil {
   445  			return nil, fmt.Errorf(
   446  				"could not decode network public key into bytes: %w",
   447  				err,
   448  			)
   449  		}
   450  		identity.NetworkPubKey, err = crypto.DecodePublicKey(
   451  			crypto.ECDSAP256,
   452  			networkKeyBytes,
   453  		)
   454  		if err != nil {
   455  			return nil, fmt.Errorf("could not decode network public key: %w", err)
   456  		}
   457  
   458  		// parse to PublicKey the staking key hex string
   459  		stakingKeyBytes, err := hex.DecodeString(string(stakingKeyHex))
   460  		if err != nil {
   461  			return nil, fmt.Errorf(
   462  				"could not decode staking public key into bytes: %w",
   463  				err,
   464  			)
   465  		}
   466  		identity.StakingPubKey, err = crypto.DecodePublicKey(
   467  			crypto.BLSBLS12381,
   468  			stakingKeyBytes,
   469  		)
   470  		if err != nil {
   471  			return nil, fmt.Errorf("could not decode staking public key: %w", err)
   472  		}
   473  
   474  		participants = append(participants, identity)
   475  	}
   476  
   477  	// IMPORTANT: returned identities must be in *canonical order*
   478  	participants = participants.Sort(flow.Canonical[flow.IdentitySkeleton])
   479  	return participants, nil
   480  }
   481  
   482  // convertClusterQCVotes converts raw cluster QC votes from the EpochCommit event
   483  // to a representation suitable for inclusion in the protocol state. Votes are
   484  // aggregated as part of this conversion.
   485  func convertClusterQCVotes(cdcClusterQCs []cadence.Value) (
   486  	[]flow.ClusterQCVoteData,
   487  	error,
   488  ) {
   489  
   490  	// avoid duplicate indices
   491  	indices := make(map[uint]struct{})
   492  	qcVoteDatas := make([]flow.ClusterQCVoteData, len(cdcClusterQCs))
   493  
   494  	// CAUTION: Votes are not validated prior to aggregation. This means a single
   495  	// invalid vote submission will result in a fully invalid QC for that cluster.
   496  	// Votes must be validated by the ClusterQC smart contract.
   497  
   498  	for _, cdcClusterQC := range cdcClusterQCs {
   499  		cdcClusterQCStruct, ok := cdcClusterQC.(cadence.Struct)
   500  		if !ok {
   501  			return nil, invalidCadenceTypeError(
   502  				"clusterQC",
   503  				cdcClusterQC,
   504  				cadence.Struct{},
   505  			)
   506  		}
   507  
   508  		if cdcClusterQCStruct.Type() == nil {
   509  			return nil, fmt.Errorf("clusterQC struct doesn't have type")
   510  		}
   511  
   512  		fields := cadence.FieldsMappedByName(cdcClusterQCStruct)
   513  
   514  		const expectedFieldCount = 4
   515  		if len(fields) < expectedFieldCount {
   516  			return nil, fmt.Errorf(
   517  				"insufficient fields (%d < %d)",
   518  				len(fields),
   519  				expectedFieldCount,
   520  			)
   521  		}
   522  
   523  		index, err := getField[cadence.UInt16](fields, "index")
   524  		if err != nil {
   525  			return nil, fmt.Errorf("failed to decode clusterQC struct: %w", err)
   526  		}
   527  
   528  		cdcRawVotes, err := getField[cadence.Array](fields, "voteSignatures")
   529  		if err != nil {
   530  			return nil, fmt.Errorf("failed to decode clusterQC struct: %w", err)
   531  		}
   532  
   533  		cdcVoterIDs, err := getField[cadence.Array](fields, "voterIDs")
   534  		if err != nil {
   535  			return nil, fmt.Errorf("failed to decode clusterQC struct: %w", err)
   536  		}
   537  
   538  		if int(index) >= len(cdcClusterQCs) {
   539  			return nil, fmt.Errorf(
   540  				"invalid index (%d) not in range [0,%d]",
   541  				index,
   542  				len(cdcClusterQCs),
   543  			)
   544  		}
   545  		_, dup := indices[uint(index)]
   546  		if dup {
   547  			return nil, fmt.Errorf("duplicate cluster QC index (%d)", index)
   548  		}
   549  
   550  		voterIDs := make([]flow.Identifier, 0, len(cdcVoterIDs.Values))
   551  		for _, cdcVoterID := range cdcVoterIDs.Values {
   552  			voterIDHex, ok := cdcVoterID.(cadence.String)
   553  			if !ok {
   554  				return nil, invalidCadenceTypeError(
   555  					"clusterQC[i].voterID",
   556  					cdcVoterID,
   557  					cadence.String(""),
   558  				)
   559  			}
   560  			voterID, err := flow.HexStringToIdentifier(string(voterIDHex))
   561  			if err != nil {
   562  				return nil, fmt.Errorf("could not convert voter ID from hex: %w", err)
   563  			}
   564  			voterIDs = append(voterIDs, voterID)
   565  		}
   566  
   567  		// gather all the vote signatures
   568  		signatures := make([]crypto.Signature, 0, len(cdcRawVotes.Values))
   569  		for _, cdcRawVote := range cdcRawVotes.Values {
   570  			rawVoteHex, ok := cdcRawVote.(cadence.String)
   571  			if !ok {
   572  				return nil, invalidCadenceTypeError(
   573  					"clusterQC[i].vote",
   574  					cdcRawVote,
   575  					cadence.String(""),
   576  				)
   577  			}
   578  			rawVoteBytes, err := hex.DecodeString(string(rawVoteHex))
   579  			if err != nil {
   580  				return nil, fmt.Errorf("could not convert raw vote from hex: %w", err)
   581  			}
   582  			signatures = append(signatures, rawVoteBytes)
   583  		}
   584  		// Aggregate BLS signatures
   585  		aggregatedSignature, err := crypto.AggregateBLSSignatures(signatures)
   586  		if err != nil {
   587  			// expected errors of the function are:
   588  			//  - empty list of signatures
   589  			//  - an input signature does not deserialize to a valid point
   590  			// Both are not expected at this stage because list is guaranteed not to be
   591  			// empty and individual signatures have been validated.
   592  			return nil, fmt.Errorf("cluster qc vote aggregation failed: %w", err)
   593  		}
   594  
   595  		// check that aggregated signature is not identity, because an identity signature
   596  		// is invalid if verified under an identity public key. This can happen in two cases:
   597  		//  - If the quorum has at least one honest signer, and given all staking key proofs of possession
   598  		//    are valid, it's extremely unlikely for the aggregated public key (and the corresponding
   599  		//    aggregated signature) to be identity.
   600  		//  - If all quorum is malicious and intentionally forge an identity aggregate. As of the previous point,
   601  		//    this is only possible if there is no honest collector involved in constructing the cluster QC.
   602  		//    Hence, the cluster would need to contain a supermajority of malicious collectors.
   603  		//    As we are assuming that the fraction of malicious collectors overall does not exceed 1/3  (measured
   604  		//    by stake), the probability for randomly assigning 2/3 or more byzantine collectors to a single cluster
   605  		//    vanishes (provided a sufficiently high collector count in total).
   606  		//
   607  		//  Note that at this level, all individual signatures are guaranteed to be valid
   608  		//  w.r.t their corresponding staking public key. It is therefore enough to check
   609  		//  the aggregated signature to conclude whether the aggregated public key is identity.
   610  		//  This check is therefore a sanity check to catch a potential issue early.
   611  		if crypto.IsBLSSignatureIdentity(aggregatedSignature) {
   612  			return nil, fmt.Errorf("cluster qc vote aggregation failed because resulting BLS signature is identity")
   613  		}
   614  
   615  		// set the fields on the QC vote data object
   616  		qcVoteDatas[int(index)] = flow.ClusterQCVoteData{
   617  			SigData:  aggregatedSignature,
   618  			VoterIDs: voterIDs,
   619  		}
   620  	}
   621  
   622  	return qcVoteDatas, nil
   623  }
   624  
   625  // convertDKGKeys converts hex-encoded DKG public keys as received by the DKG
   626  // smart contract into crypto.PublicKey representations suitable for inclusion
   627  // in the protocol state.
   628  func convertDKGKeys(cdcDKGKeys []cadence.Value) (
   629  	groupKey crypto.PublicKey,
   630  	participantKeys []crypto.PublicKey,
   631  	err error,
   632  ) {
   633  
   634  	hexDKGKeys := make([]string, 0, len(cdcDKGKeys))
   635  	for _, value := range cdcDKGKeys {
   636  		keyHex, ok := value.(cadence.String)
   637  		if !ok {
   638  			return nil, nil, invalidCadenceTypeError("dkgKey", value, cadence.String(""))
   639  		}
   640  		hexDKGKeys = append(hexDKGKeys, string(keyHex))
   641  	}
   642  
   643  	// pop first element - group public key hex string
   644  	groupPubKeyHex := hexDKGKeys[0]
   645  	hexDKGKeys = hexDKGKeys[1:]
   646  
   647  	// decode group public key
   648  	groupKeyBytes, err := hex.DecodeString(groupPubKeyHex)
   649  	if err != nil {
   650  		return nil, nil, fmt.Errorf(
   651  			"could not decode group public key into bytes: %w",
   652  			err,
   653  		)
   654  	}
   655  	groupKey, err = crypto.DecodePublicKey(crypto.BLSBLS12381, groupKeyBytes)
   656  	if err != nil {
   657  		return nil, nil, fmt.Errorf("could not decode group public key: %w", err)
   658  	}
   659  
   660  	// decode individual public keys
   661  	dkgParticipantKeys := make([]crypto.PublicKey, 0, len(hexDKGKeys))
   662  	for _, pubKeyString := range hexDKGKeys {
   663  
   664  		pubKeyBytes, err := hex.DecodeString(pubKeyString)
   665  		if err != nil {
   666  			return nil, nil, fmt.Errorf(
   667  				"could not decode individual public key into bytes: %w",
   668  				err,
   669  			)
   670  		}
   671  		pubKey, err := crypto.DecodePublicKey(crypto.BLSBLS12381, pubKeyBytes)
   672  		if err != nil {
   673  			return nil, nil, fmt.Errorf("could not decode dkg public key: %w", err)
   674  		}
   675  		dkgParticipantKeys = append(dkgParticipantKeys, pubKey)
   676  	}
   677  
   678  	return groupKey, dkgParticipantKeys, nil
   679  }
   680  
   681  func invalidCadenceTypeError(
   682  	fieldName string,
   683  	actualType, expectedType cadence.Value,
   684  ) error {
   685  	return fmt.Errorf(
   686  		"invalid Cadence type for field %s (got=%s, expected=%s)",
   687  		fieldName,
   688  		actualType.Type().ID(),
   689  		expectedType.Type().ID(),
   690  	)
   691  }
   692  
   693  // convertServiceEventProtocolStateVersionUpgrade converts a Cadence instance of the VersionBeacon
   694  // service event to the protocol-internal representation.
   695  // CAUTION: This function must only be used for input events computed locally, by an
   696  // Execution or Verification Node; it is not resilient to malicious inputs.
   697  // No errors are expected during normal operation.
   698  func convertServiceEventProtocolStateVersionUpgrade(event flow.Event) (*flow.ServiceEvent, error) {
   699  	payload, err := ccf.Decode(nil, event.Payload)
   700  	if err != nil {
   701  		return nil, fmt.Errorf("could not unmarshal event payload: %w", err)
   702  	}
   703  
   704  	versionUpgrade, err := DecodeCadenceValue("ProtocolStateVersionUpgrade payload", payload,
   705  		func(cdcEvent cadence.Event) (*flow.ProtocolStateVersionUpgrade, error) {
   706  
   707  			if cdcEvent.Type() == nil {
   708  				return nil, fmt.Errorf("ProtocolStateVersionUpgrade event doesn't have type")
   709  			}
   710  
   711  			fields := cadence.FieldsMappedByName(cdcEvent)
   712  
   713  			const expectedFieldCount = 2
   714  			if len(fields) < expectedFieldCount {
   715  				return nil, fmt.Errorf("unexpected number of fields in ProtocolStateVersionUpgrade (%d < %d)",
   716  					len(fields), expectedFieldCount)
   717  			}
   718  
   719  			newProtocolVersionValue, err := getField[cadence.Value](fields, "newProtocolVersion")
   720  			if err != nil {
   721  				return nil, fmt.Errorf("failed to decode VersionBeacon event: %w", err)
   722  			}
   723  
   724  			activeViewValue, err := getField[cadence.Value](fields, "activeView")
   725  			if err != nil {
   726  				return nil, fmt.Errorf("failed to decode VersionBeacon event: %w", err)
   727  			}
   728  
   729  			newProtocolVersion, err := DecodeCadenceValue(
   730  				".newProtocolVersion", newProtocolVersionValue, func(cadenceVal cadence.UInt64) (uint64, error) {
   731  					return uint64(cadenceVal), err
   732  				},
   733  			)
   734  			if err != nil {
   735  				return nil, err
   736  			}
   737  			activeView, err := DecodeCadenceValue(
   738  				".activeView", activeViewValue, func(cadenceVal cadence.UInt64) (uint64, error) {
   739  					return uint64(cadenceVal), err
   740  				},
   741  			)
   742  			if err != nil {
   743  				return nil, err
   744  			}
   745  
   746  			return &flow.ProtocolStateVersionUpgrade{
   747  				NewProtocolStateVersion: newProtocolVersion,
   748  				ActiveView:              activeView,
   749  			}, nil
   750  		})
   751  	if err != nil {
   752  		return nil, fmt.Errorf("could not decode cadence value: %w", err)
   753  	}
   754  
   755  	// create the service event
   756  	serviceEvent := &flow.ServiceEvent{
   757  		Type:  flow.ServiceEventProtocolStateVersionUpgrade,
   758  		Event: versionUpgrade,
   759  	}
   760  	return serviceEvent, nil
   761  }
   762  
   763  // convertServiceEventVersionBeacon converts a Cadence instance of the VersionBeacon
   764  // service event to the protocol-internal representation.
   765  // CAUTION: This function must only be used for input events computed locally, by an
   766  // Execution or Verification Node; it is not resilient to malicious inputs.
   767  // No errors are expected during normal operation.
   768  func convertServiceEventVersionBeacon(event flow.Event) (*flow.ServiceEvent, error) {
   769  	payload, err := ccf.Decode(nil, event.Payload)
   770  	if err != nil {
   771  		return nil, fmt.Errorf("could not unmarshal event payload: %w", err)
   772  	}
   773  
   774  	versionBeacon, err := DecodeCadenceValue(
   775  		"VersionBeacon payload", payload, func(cdcEvent cadence.Event) (*flow.VersionBeacon, error) {
   776  
   777  			if cdcEvent.Type() == nil {
   778  				return nil, fmt.Errorf("VersionBeacon event doesn't have type")
   779  			}
   780  
   781  			fields := cadence.FieldsMappedByName(cdcEvent)
   782  
   783  			const expectedFieldCount = 2
   784  			if len(fields) != expectedFieldCount {
   785  				return nil, fmt.Errorf(
   786  					"unexpected number of fields in VersionBeacon event (%d != %d)",
   787  					len(fields),
   788  					expectedFieldCount,
   789  				)
   790  			}
   791  
   792  			versionBoundariesValue, err := getField[cadence.Value](fields, "versionBoundaries")
   793  			if err != nil {
   794  				return nil, fmt.Errorf("failed to decode VersionBeacon event: %w", err)
   795  			}
   796  
   797  			sequenceValue, err := getField[cadence.Value](fields, "sequence")
   798  			if err != nil {
   799  				return nil, fmt.Errorf("failed to decode VersionBeacon event: %w", err)
   800  			}
   801  
   802  			versionBoundaries, err := DecodeCadenceValue(
   803  				".versionBoundaries", versionBoundariesValue, convertVersionBoundaries,
   804  			)
   805  			if err != nil {
   806  				return nil, err
   807  			}
   808  
   809  			sequence, err := DecodeCadenceValue(
   810  				".sequence", sequenceValue, func(cadenceVal cadence.UInt64) (
   811  					uint64,
   812  					error,
   813  				) {
   814  					return uint64(cadenceVal), nil
   815  				},
   816  			)
   817  			if err != nil {
   818  				return nil, err
   819  			}
   820  
   821  			return &flow.VersionBeacon{
   822  				VersionBoundaries: versionBoundaries,
   823  				Sequence:          sequence,
   824  			}, err
   825  		},
   826  	)
   827  	if err != nil {
   828  		return nil, err
   829  	}
   830  
   831  	// a converted version beacon event should also be valid
   832  	if err := versionBeacon.Validate(); err != nil {
   833  		return nil, fmt.Errorf("invalid VersionBeacon event: %w", err)
   834  	}
   835  
   836  	// create the service event
   837  	serviceEvent := &flow.ServiceEvent{
   838  		Type:  flow.ServiceEventVersionBeacon,
   839  		Event: versionBeacon,
   840  	}
   841  
   842  	return serviceEvent, nil
   843  }
   844  
   845  func convertVersionBoundaries(array cadence.Array) (
   846  	[]flow.VersionBoundary,
   847  	error,
   848  ) {
   849  	boundaries := make([]flow.VersionBoundary, len(array.Values))
   850  
   851  	for i, cadenceVal := range array.Values {
   852  		boundary, err := DecodeCadenceValue(
   853  			fmt.Sprintf(".Values[%d]", i),
   854  			cadenceVal,
   855  			func(structVal cadence.Struct) (
   856  				flow.VersionBoundary,
   857  				error,
   858  			) {
   859  				if structVal.Type() == nil {
   860  					return flow.VersionBoundary{}, fmt.Errorf("VersionBoundary struct doesn't have type")
   861  				}
   862  
   863  				fields := cadence.FieldsMappedByName(structVal)
   864  
   865  				const expectedFieldCount = 2
   866  				if len(fields) < expectedFieldCount {
   867  					return flow.VersionBoundary{}, fmt.Errorf(
   868  						"incorrect number of fields (%d != %d)",
   869  						len(fields),
   870  						expectedFieldCount,
   871  					)
   872  				}
   873  
   874  				blockHeightValue, err := getField[cadence.Value](fields, "blockHeight")
   875  				if err != nil {
   876  					return flow.VersionBoundary{}, fmt.Errorf("failed to decode VersionBoundary struct: %w", err)
   877  				}
   878  
   879  				versionValue, err := getField[cadence.Value](fields, "version")
   880  				if err != nil {
   881  					return flow.VersionBoundary{}, fmt.Errorf("failed to decode VersionBoundary struct: %w", err)
   882  				}
   883  
   884  				height, err := DecodeCadenceValue(
   885  					".blockHeight",
   886  					blockHeightValue,
   887  					func(cadenceVal cadence.UInt64) (
   888  						uint64,
   889  						error,
   890  					) {
   891  						return uint64(cadenceVal), nil
   892  					},
   893  				)
   894  				if err != nil {
   895  					return flow.VersionBoundary{}, err
   896  				}
   897  
   898  				version, err := DecodeCadenceValue(
   899  					".version",
   900  					versionValue,
   901  					convertSemverVersion,
   902  				)
   903  				if err != nil {
   904  					return flow.VersionBoundary{}, err
   905  				}
   906  
   907  				return flow.VersionBoundary{
   908  					BlockHeight: height,
   909  					Version:     version,
   910  				}, nil
   911  			},
   912  		)
   913  		if err != nil {
   914  			return nil, err
   915  		}
   916  		boundaries[i] = boundary
   917  	}
   918  
   919  	return boundaries, nil
   920  }
   921  
   922  func convertSemverVersion(structVal cadence.Struct) (
   923  	string,
   924  	error,
   925  ) {
   926  	if structVal.Type() == nil {
   927  		return "", fmt.Errorf("Semver struct doesn't have type")
   928  	}
   929  
   930  	fields := cadence.FieldsMappedByName(structVal)
   931  
   932  	const expectedFieldCount = 4
   933  	if len(fields) < expectedFieldCount {
   934  		return "", fmt.Errorf(
   935  			"incorrect number of fields (%d != %d)",
   936  			len(fields),
   937  			expectedFieldCount,
   938  		)
   939  	}
   940  
   941  	majorValue, err := getField[cadence.Value](fields, "major")
   942  	if err != nil {
   943  		return "", fmt.Errorf("failed to decode SemVer struct: %w", err)
   944  	}
   945  
   946  	minorValue, err := getField[cadence.Value](fields, "minor")
   947  	if err != nil {
   948  		return "", fmt.Errorf("failed to decode SemVer struct: %w", err)
   949  	}
   950  
   951  	patchValue, err := getField[cadence.Value](fields, "patch")
   952  	if err != nil {
   953  		return "", fmt.Errorf("failed to decode SemVer struct: %w", err)
   954  	}
   955  
   956  	preReleaseValue, err := getField[cadence.Value](fields, "preRelease")
   957  	if err != nil {
   958  		return "", fmt.Errorf("failed to decode SemVer struct: %w", err)
   959  	}
   960  
   961  	major, err := DecodeCadenceValue(
   962  		".major",
   963  		majorValue,
   964  		func(cadenceVal cadence.UInt8) (
   965  			uint64,
   966  			error,
   967  		) {
   968  			return uint64(cadenceVal), nil
   969  		},
   970  	)
   971  	if err != nil {
   972  		return "", err
   973  	}
   974  
   975  	minor, err := DecodeCadenceValue(
   976  		".minor",
   977  		minorValue,
   978  		func(cadenceVal cadence.UInt8) (
   979  			uint64,
   980  			error,
   981  		) {
   982  			return uint64(cadenceVal), nil
   983  		},
   984  	)
   985  	if err != nil {
   986  		return "", err
   987  	}
   988  
   989  	patch, err := DecodeCadenceValue(
   990  		".patch",
   991  		patchValue,
   992  		func(cadenceVal cadence.UInt8) (
   993  			uint64,
   994  			error,
   995  		) {
   996  			return uint64(cadenceVal), nil
   997  		},
   998  	)
   999  	if err != nil {
  1000  		return "", err
  1001  	}
  1002  
  1003  	preRelease, err := DecodeCadenceValue(
  1004  		".preRelease",
  1005  		preReleaseValue,
  1006  		func(cadenceVal cadence.Optional) (
  1007  			string,
  1008  			error,
  1009  		) {
  1010  			if cadenceVal.Value == nil {
  1011  				return "", nil
  1012  			}
  1013  
  1014  			return DecodeCadenceValue(
  1015  				"!",
  1016  				cadenceVal.Value,
  1017  				func(cadenceVal cadence.String) (
  1018  					string,
  1019  					error,
  1020  				) {
  1021  					return string(cadenceVal), nil
  1022  				},
  1023  			)
  1024  		},
  1025  	)
  1026  	if err != nil {
  1027  		return "", err
  1028  	}
  1029  
  1030  	version := semver.Version{
  1031  		Major:      int64(major),
  1032  		Minor:      int64(minor),
  1033  		Patch:      int64(patch),
  1034  		PreRelease: semver.PreRelease(preRelease),
  1035  	}
  1036  
  1037  	return version.String(), nil
  1038  
  1039  }
  1040  
  1041  type decodeError struct {
  1042  	location string
  1043  	err      error
  1044  }
  1045  
  1046  func (e decodeError) Error() string {
  1047  	if e.err != nil {
  1048  		return fmt.Sprintf("decoding error %s: %s", e.location, e.err.Error())
  1049  	}
  1050  	return fmt.Sprintf("decoding error %s", e.location)
  1051  }
  1052  
  1053  func (e decodeError) Unwrap() error {
  1054  	return e.err
  1055  }
  1056  
  1057  func DecodeCadenceValue[From cadence.Value, Into any](
  1058  	location string,
  1059  	value cadence.Value,
  1060  	decodeInner func(From) (Into, error),
  1061  ) (Into, error) {
  1062  	var defaultInto Into
  1063  	if value == nil {
  1064  		return defaultInto, decodeError{
  1065  			location: location,
  1066  			err:      nil,
  1067  		}
  1068  	}
  1069  
  1070  	convertedValue, is := value.(From)
  1071  	if !is {
  1072  		return defaultInto, decodeError{
  1073  			location: location,
  1074  			err: fmt.Errorf(
  1075  				"invalid Cadence type (got=%T, expected=%T)",
  1076  				value,
  1077  				*new(From),
  1078  			),
  1079  		}
  1080  	}
  1081  
  1082  	inner, err := decodeInner(convertedValue)
  1083  	if err != nil {
  1084  		if err, is := err.(decodeError); is {
  1085  			return defaultInto, decodeError{
  1086  				location: location + err.location,
  1087  				err:      err.err,
  1088  			}
  1089  		}
  1090  		return defaultInto, decodeError{
  1091  			location: location,
  1092  			err:      err,
  1093  		}
  1094  	}
  1095  
  1096  	return inner, nil
  1097  }