Example #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);
            }
        }
Example #2
0
        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
        }