Пример #1
0
        public async Task ProcessProposalDutiesAsync(Slot slot, CancellationToken cancellationToken)
        {
            // If proposer, get block, sign block, return to node
            // Retry if not successful; need to queue this up to send immediately if connection issue. (or broadcast?)

            BlsPublicKey?blsPublicKey = _validatorState.GetProposalDutyForSlot(slot);

            if (!(blsPublicKey is null))
            {
                if (_logger.IsInfo())
                {
                    Log.ProposalDutyFor(_logger, slot, blsPublicKey, null);
                }

                BlsSignature randaoReveal = GetEpochSignature(slot, blsPublicKey);

                if (_logger.IsDebug())
                {
                    LogDebug.RequestingBlock(_logger, slot, blsPublicKey.ToShortString(), randaoReveal.ToString().Substring(0, 10), null);
                }

                BeaconBlock unsignedBlock = await _beaconNodeApi.NewBlockAsync(slot, randaoReveal, cancellationToken).ConfigureAwait(false);

                BeaconBlock signedBlock = SignBlock(unsignedBlock, blsPublicKey);

                if (_logger.IsDebug())
                {
                    LogDebug.PublishingSignedBlock(_logger, slot, blsPublicKey.ToShortString(), randaoReveal.ToString().Substring(0, 10), signedBlock, signedBlock.Signature.ToString().Substring(0, 10), null);
                }

                bool nodeAccepted = await _beaconNodeApi.PublishBlockAsync(signedBlock, cancellationToken).ConfigureAwait(false);

                _validatorState.ClearProposalDutyForSlot(slot);
            }
        }
Пример #2
0
        // ReSharper disable once InconsistentNaming
        // ReSharper disable once IdentifierTypo
        public async Task <IActionResult> GetAsync([FromQuery] ulong slot, [FromQuery] byte[] randao_reveal,
                                                   CancellationToken cancellationToken)
        {
            if (_logger.IsInfo())
            {
                Log.NewBlockRequested(_logger, slot, Bytes.ToHexString(randao_reveal), null);
            }

            Slot         targetSlot   = new Slot(slot);
            BlsSignature randaoReveal = new BlsSignature(randao_reveal);

            ApiResponse <BeaconBlock> apiResponse =
                await _beaconNode.NewBlockAsync(targetSlot, randaoReveal, cancellationToken).ConfigureAwait(false);

            switch (apiResponse.StatusCode)
            {
            case Core2.Api.StatusCode.Success:
                return(Ok(apiResponse.Content));

            case Core2.Api.StatusCode.InvalidRequest:
                return(Problem("Invalid request syntax.", statusCode: (int)apiResponse.StatusCode));

            case Core2.Api.StatusCode.CurrentlySyncing:
                return(Problem("Beacon node is currently syncing, try again later.",
                               statusCode: (int)apiResponse.StatusCode));
            }

            return(Problem("Beacon node internal error.", statusCode: (int)apiResponse.StatusCode));
        }
Пример #3
0
        /// <summary>Produce a new block, without signature.</summary>
        /// <param name="slot">The slot for which the block should be proposed.</param>
        /// <param name="randao_reveal">The validator's randao reveal value.</param>
        /// <returns>Success response</returns>
        public async Task <BeaconBlock> BlockAsync(ulong slot, byte[] randao_reveal)
        {
            Containers.BeaconBlock data =
                await _beaconNode.NewBlockAsync(new Slot(slot), new BlsSignature(randao_reveal));

            OApi.BeaconBlock result = new OApi.BeaconBlock()
            {
                Slot        = (ulong)data.Slot,
                Parent_root = data.ParentRoot.ToString(),
                State_root  = data.StateRoot.ToString(),
                Signature   = data.Signature.ToString(),
                Body        = new OApi.BeaconBlockBody()
                {
                    Randao_reveal = data.Body !.RandaoReveal.AsSpan().ToArray(),
                    Eth1_data     = new Eth1_data()
                    {
                        Block_hash    = data.Body.Eth1Data.BlockHash.Bytes,
                        Deposit_count = (int)data.Body.Eth1Data.DepositCount,
                        Deposit_root  = data.Body.Eth1Data.DepositRoot.Bytes
                    },
                    Graffiti           = data.Body.Graffiti.AsSpan().ToArray(),
                    Proposer_slashings = data.Body.ProposerSlashings.Select(x => new Proposer_slashings()
                    {
                        Header_1       = MapBeaconBlockHeader(x.Header1),
                        Header_2       = MapBeaconBlockHeader(x.Header2),
                        Proposer_index = (int)x.ProposerIndex
                    }).ToList(),
                    Attester_slashings = data.Body.AttesterSlashings.Select(x => new Attester_slashings()
                    {
                        Attestation_1 = MapIndexedAttestation(x.Attestation1),
                        Attestation_2 = MapIndexedAttestation(x.Attestation2)
                    }).ToList(),
                    Attestations = data.Body.Attestations.Select(x => new Attestations()
                    {
                        Signature        = x.Signature.Bytes,
                        Aggregation_bits = x.AggregationBits.Cast <byte>().ToArray(),
                        Custody_bits     = x.CustodyBits.Cast <byte>().ToArray(),
                        Data             = MapAttestationData(x.Data)
                    }).ToList(),
                    Voluntary_exits = data.Body.VoluntaryExits.Select(x => new Voluntary_exits()
                    {
                        Validator_index = (int)x.ValidatorIndex,
                        Epoch           = x.Epoch,
                        Signature       = x.Signature.Bytes
                    }).ToList(),
                    Deposits = data.Body.Deposits.Select((x, index) => new Deposits()
                    {
                        Index = index,
                        Proof = x.Proof.Select(y => y.Bytes).ToList(),
                        Data  = new Data()
                        {
                            Amount    = (int)(ulong)x.Data.Amount,
                            Pubkey    = x.Data.PublicKey.Bytes,
                            Signature = x.Data.Signature.Bytes,
                            Withdrawal_credentials = x.Data.WithdrawalCredentials.Bytes
                        }
                    }).ToList(),
                }
            };
            return(result);
        }
Пример #4
0
        public async Task ProcessProposalDutiesAsync(Slot slot, CancellationToken cancellationToken)
        {
            // If proposer, get block, sign block, return to node
            // Retry if not successful; need to queue this up to send immediately if connection issue. (or broadcast?)

            BlsPublicKey?blsPublicKey = _validatorState.GetProposalDutyForSlot(slot);

            if (!(blsPublicKey is null))
            {
                Activity activity = new Activity("process-proposal-duty");
                activity.Start();
                try
                {
                    if (_logger.IsInfo())
                    {
                        Log.ProposalDutyFor(_logger, slot, _beaconChainInformation.Time, blsPublicKey, null);
                    }

                    BlsSignature randaoReveal = GetEpochSignature(slot, blsPublicKey);

                    if (_logger.IsDebug())
                    {
                        LogDebug.RequestingBlock(_logger, slot, blsPublicKey.ToShortString(),
                                                 randaoReveal.ToString().Substring(0, 10), null);
                    }

                    ApiResponse <BeaconBlock> newBlockResponse = await _beaconNodeApi
                                                                 .NewBlockAsync(slot, randaoReveal, cancellationToken).ConfigureAwait(false);

                    if (newBlockResponse.StatusCode == StatusCode.Success)
                    {
                        BeaconBlock       unsignedBlock  = newBlockResponse.Content;
                        BlsSignature      blockSignature = GetBlockSignature(unsignedBlock, blsPublicKey);
                        SignedBeaconBlock signedBlock    = new SignedBeaconBlock(unsignedBlock, blockSignature);

                        if (_logger.IsDebug())
                        {
                            LogDebug.PublishingSignedBlock(_logger, slot, blsPublicKey.ToShortString(),
                                                           randaoReveal.ToString().Substring(0, 10), signedBlock.Message,
                                                           signedBlock.Signature.ToString().Substring(0, 10), null);
                        }

                        ApiResponse publishBlockResponse = await _beaconNodeApi
                                                           .PublishBlockAsync(signedBlock, cancellationToken)
                                                           .ConfigureAwait(false);

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

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