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); } }
// 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)); }
/// <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); }
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(); } } }