/// <summary> /// Check if ``indexed_attestation`` has valid indices and signature. /// </summary> public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain) { MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue; IReadOnlyList <ValidatorIndex> attestingIndices = indexedAttestation.AttestingIndices; // Verify max number of indices if ((ulong)attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, attestingIndices.Count, miscellaneousParameters.MaximumValidatorsPerCommittee, null); } return(false); } // Verify indices are sorted and unique if (attestingIndices.Count() > 1) { for (int index = 0; index < attestingIndices.Count() - 1; index++) { if (!(attestingIndices[index] < attestingIndices[index + 1])) { if (attestingIndices[index] == attestingIndices[index + 1]) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationNotUnique(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null); } } else { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null); } } return(false); } } } // TODO: BLS FastAggregateVerify (see spec) // Verify aggregate signature IList <BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int)(ulong)x].PublicKey) .ToList(); Root attestationDataRoot = _cryptographyService.HashTreeRoot(indexedAttestation.Data); Root signingRoot = ComputeSigningRoot(attestationDataRoot, domain); BlsSignature signature = indexedAttestation.Signature; //BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys); //bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, signingRoot, signature); bool isValid = _cryptographyService.BlsFastAggregateVerify(publicKeys, signingRoot, signature); if (!isValid) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, null); } return(false); } return(true); }