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); } }
public async Task <IActionResult> GetAsync([FromBody] SignedBeaconBlock signedBeaconBlock, CancellationToken cancellationToken) { if (_logger.IsInfo()) { Log.BlockPublished(_logger, signedBeaconBlock.Message?.Slot, signedBeaconBlock.Message?.Body?.RandaoReveal, signedBeaconBlock.Message?.ParentRoot, signedBeaconBlock.Message?.StateRoot, signedBeaconBlock.Message?.Body?.Graffiti, signedBeaconBlock.Signature, null); } ApiResponse apiResponse = await _beaconNode.PublishBlockAsync(signedBeaconBlock, cancellationToken).ConfigureAwait(false); return(apiResponse.StatusCode switch { // "The block was validated successfully and has been broadcast. It has also been integrated into the beacon node's database." Core2.Api.StatusCode.Success => Ok(), // "The block failed validation, but was successfully broadcast anyway. It was not integrated into the beacon node's database." Core2.Api.StatusCode.BroadcastButFailedValidation => Accepted(), 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) });
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(); } } }
/// <summary>Publish a signed block.</summary> /// <param name="beacon_block">The `BeaconBlock` object, as sent from the beacon node originally, but now with the signature field completed.</param> /// <returns>The block was validated successfully and has been broadcast. It has also been integrated into the beacon node's database.</returns> public async Task Block2Async(BeaconBlock beacon_block) { if (_logger.IsInfo()) { Log.BlockPublished(_logger, beacon_block.Slot, Bytes.ToHexString(beacon_block.Body.Randao_reveal), beacon_block.Parent_root, beacon_block.State_root, Bytes.ToHexString(beacon_block.Body.Graffiti), beacon_block.Signature, null); } Core2.Containers.BeaconBlock signedBlock = new Core2.Containers.BeaconBlock( new Slot((ulong)beacon_block.Slot), new Hash32(Bytes.FromHexString(beacon_block.Parent_root)), new Hash32(Bytes.FromHexString(beacon_block.State_root)), new Core2.Containers.BeaconBlockBody( new BlsSignature(beacon_block.Body.Randao_reveal), new Eth1Data( new Hash32(beacon_block.Body.Eth1_data.Deposit_root), (ulong)beacon_block.Body.Eth1_data.Deposit_count, new Hash32(beacon_block.Body.Eth1_data.Block_hash) ), new Bytes32(beacon_block.Body.Graffiti), beacon_block.Body.Proposer_slashings.Select(x => new ProposerSlashing( new ValidatorIndex((ulong)x.Proposer_index), MapBeaconBlockHeader(x.Header_1), MapBeaconBlockHeader(x.Header_2) )), beacon_block.Body.Attester_slashings.Select(x => new AttesterSlashing( MapIndexedAttestation(x.Attestation_1), MapIndexedAttestation(x.Attestation_2) )), beacon_block.Body.Attestations.Select(x => new Core2.Containers.Attestation( new BitArray(x.Aggregation_bits), MapAttestationData(x.Data), new BlsSignature(x.Signature) ) ), beacon_block.Body.Deposits.Select(x => new Core2.Containers.Deposit( x.Proof.Select(y => new Hash32(y)), new DepositData( new BlsPublicKey(x.Data.Pubkey), new Hash32(x.Data.Withdrawal_credentials), new Gwei((ulong)x.Data.Amount), new BlsSignature(x.Data.Signature) ) ) ), beacon_block.Body.Voluntary_exits.Select(x => new Core2.Containers.VoluntaryExit( new Epoch((ulong)x.Epoch), new ValidatorIndex((ulong)x.Validator_index), new BlsSignature((x.Signature)) ) ) ), new BlsSignature(Bytes.FromHexString(beacon_block.Signature)) ); bool acceptedLocally = await _beaconNode.PublishBlockAsync(signedBlock, CancellationToken.None); // TODO: return 200 or 202 based on whether accepted locally or not }