Пример #1
0
        // ReSharper disable once InconsistentNaming
        // ReSharper disable once IdentifierTypo
        public async Task <IActionResult> GetAsync([FromQuery] byte[] validator_pubkey, [FromQuery] uint poc_bit,
                                                   [FromQuery] ulong slot, [FromQuery] ulong index,
                                                   CancellationToken cancellationToken)
        {
            if (_logger.IsDebug())
            {
                LogDebug.NewAttestationRequested(_logger, slot, index, Bytes.ToHexString(validator_pubkey), null);
            }

            BlsPublicKey validatorPublicKey = new BlsPublicKey(validator_pubkey);
            bool         proofOfCustodyBit  = poc_bit > 0;
            Slot         targetSlot         = new Slot(slot);

            // NOTE: Spec 0.10.1 still has old Shard references in OAPI, although the spec has changed to Index;
            // use Index as it is easier to understand (i.e. the spec OAPI in 0.10.1 is wrong)
            CommitteeIndex targetIndex = new CommitteeIndex(index);

            ApiResponse <Attestation> apiResponse =
                await _beaconNode
                .NewAttestationAsync(validatorPublicKey, proofOfCustodyBit, targetSlot, targetIndex,
                                     cancellationToken).ConfigureAwait(false);

            return(apiResponse.StatusCode switch
            {
                Core2.Api.StatusCode.Success => Ok(apiResponse.Content),
                Core2.Api.StatusCode.InvalidRequest => Problem("Invalid request syntax.",
                                                               statusCode: (int)apiResponse.StatusCode),
                Core2.Api.StatusCode.CurrentlySyncing => Problem("Beacon node is currently syncing, try again later.",
                                                                 statusCode: (int)apiResponse.StatusCode),
                _ => Problem("Beacon node internal error.", statusCode: (int)apiResponse.StatusCode)
            });
Пример #2
0
        public async Task ProcessAttestationDutiesAsync(Slot slot, CancellationToken cancellationToken)
        {
            // If attester, get attestation, sign attestation, return to node

            IList <(BlsPublicKey, CommitteeIndex)>
            attestationDutyList = _validatorState.GetAttestationDutyForSlot(slot);

            foreach ((BlsPublicKey validatorPublicKey, CommitteeIndex index) in attestationDutyList)
            {
                Activity activity = new Activity("process-attestation-duty");
                activity.Start();
                using IDisposable activityScope = _logger.BeginScope("[TraceId, {TraceId}], [SpanId, {SpanId}]",
                                                                     activity.TraceId, activity.SpanId);
                try
                {
                    if (_logger.IsDebug())
                    {
                        LogDebug.RequestingAttestationFor(_logger, slot, _beaconChainInformation.Time,
                                                          validatorPublicKey,
                                                          null);
                    }

                    ApiResponse <Attestation> newAttestationResponse = await _beaconNodeApi
                                                                       .NewAttestationAsync(validatorPublicKey, false, slot, index, cancellationToken)
                                                                       .ConfigureAwait(false);

                    if (newAttestationResponse.StatusCode == StatusCode.Success)
                    {
                        Attestation  unsignedAttestation  = newAttestationResponse.Content;
                        BlsSignature attestationSignature =
                            await GetAttestationSignatureAsync(unsignedAttestation, validatorPublicKey)
                            .ConfigureAwait(false);

                        Attestation signedAttestation = new Attestation(unsignedAttestation.AggregationBits,
                                                                        unsignedAttestation.Data, attestationSignature);

                        // TODO: Getting one attestation at a time probably isn't very scalable.
                        // All validators are attesting the same data, just in different committees with different indexes
                        // => Get the data once, group relevant validators by committee, sign and aggregate within each
                        // committee (marking relevant aggregation bits), then publish one pre-aggregated value?

                        if (_logger.IsDebug())
                        {
                            LogDebug.PublishingSignedAttestation(_logger, slot, index,
                                                                 validatorPublicKey.ToShortString(),
                                                                 signedAttestation.Data,
                                                                 signedAttestation.Signature.ToString().Substring(0, 10), null);
                        }

                        ApiResponse publishAttestationResponse = await _beaconNodeApi
                                                                 .PublishAttestationAsync(signedAttestation, cancellationToken)
                                                                 .ConfigureAwait(false);

                        if (publishAttestationResponse.StatusCode != StatusCode.Success &&
                            publishAttestationResponse.StatusCode !=
                            StatusCode.BroadcastButFailedValidation)
                        {
                            throw new Exception(
                                      $"Error response from publish: {(int) publishAttestationResponse.StatusCode} {publishAttestationResponse.StatusCode}.");
                        }

                        bool nodeAccepted = publishAttestationResponse.StatusCode == StatusCode.Success;
                        // TODO: Log warning if not accepted? Not sure what else we could do.
                    }
                }
                catch (Exception ex)
                {
                    Log.ExceptionProcessingAttestationDuty(_logger, slot, validatorPublicKey, ex.Message, ex);
                }
                finally
                {
                    activity.Stop();
                }

                _validatorState.ClearAttestationDutyForSlot(slot);
            }
        }