/// <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 }
public async Task <bool> PublishBlockAsync(Core2.Containers.BeaconBlock block, CancellationToken cancellationToken) { BeaconNode.OApiClient.BeaconBlock data = new BeaconNode.OApiClient.BeaconBlock() { Slot = block.Slot, Parent_root = block.ParentRoot.ToString(), State_root = block.StateRoot.ToString(), Signature = block.Signature.ToString(), Body = new BeaconNode.OApiClient.BeaconBlockBody() { Randao_reveal = block.Body !.RandaoReveal.AsSpan().ToArray(), Eth1_data = new Eth1_data() { Block_hash = block.Body.Eth1Data.BlockHash.Bytes, Deposit_count = block.Body.Eth1Data.DepositCount, Deposit_root = block.Body.Eth1Data.DepositRoot.Bytes }, Graffiti = block.Body.Graffiti.AsSpan().ToArray(), Proposer_slashings = block.Body.ProposerSlashings.Select(x => new Proposer_slashings() { Header_1 = MapBeaconBlockHeader(x.Header1), Header_2 = MapBeaconBlockHeader(x.Header2), Proposer_index = x.ProposerIndex }).ToList(), Attester_slashings = block.Body.AttesterSlashings.Select(x => new Attester_slashings() { Attestation_1 = MapIndexedAttestation(x.Attestation1), Attestation_2 = MapIndexedAttestation(x.Attestation2) }).ToList(), Attestations = block.Body.Attestations.Select(x => new Attestations() { Signature = x.Signature.Bytes, Aggregation_bits = x.AggregationBits.Cast <byte>().ToArray(), Custody_bits = new byte[0], Data = MapAttestationData(x.Data) }).ToList(), Voluntary_exits = block.Body.VoluntaryExits.Select(x => new Voluntary_exits() { Validator_index = x.ValidatorIndex, Epoch = x.Epoch, Signature = x.Signature.Bytes }).ToList(), Deposits = block.Body.Deposits.Select((x, index) => new Deposits() { Index = (ulong)index, Proof = x.Proof.Select(y => y.Bytes).ToList(), Data = new Data() { Amount = x.Data.Amount, Pubkey = x.Data.PublicKey.Bytes, Signature = x.Data.Signature.Bytes, Withdrawal_credentials = x.Data.WithdrawalCredentials.Bytes } }).ToList(), } }; await ClientOperationWithRetry(async (oapiClient, innerCancellationToken) => { await oapiClient.Block2Async(data, innerCancellationToken).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); // TODO: Parse 202 result separate from 200 result return(true); }
/// <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) { if (_logger.IsInfo()) { Log.NewBlockRequested(_logger, slot, Bytes.ToHexString(randao_reveal), null); } Core2.Containers.BeaconBlock data = await _beaconNode.NewBlockAsync(new Slot(slot), new BlsSignature(randao_reveal), CancellationToken.None); 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 = 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 = 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 = new byte[0], Data = MapAttestationData(x.Data) }).ToList(), Voluntary_exits = data.Body.VoluntaryExits.Select(x => new Voluntary_exits() { Validator_index = x.ValidatorIndex, Epoch = x.Epoch, Signature = x.Signature.Bytes }).ToList(), Deposits = data.Body.Deposits.Select((x, index) => new Deposits() { Index = (ulong)index, Proof = x.Proof.Select(y => y.Bytes).ToList(), Data = new Data() { Amount = x.Data.Amount, Pubkey = x.Data.PublicKey.Bytes, Signature = x.Data.Signature.Bytes, Withdrawal_credentials = x.Data.WithdrawalCredentials.Bytes } }).ToList(), Transfers = new List <Transfers>() } }; return(result); }
public async Task <Core2.Containers.BeaconBlock> NewBlockAsync(Slot slot, BlsSignature randaoReveal, CancellationToken cancellationToken) { ulong slotValue = (ulong)slot; byte[] randaoRevealBytes = randaoReveal.Bytes; BeaconNode.OApiClient.BeaconBlock?result = null; await ClientOperationWithRetry(async (oapiClient, innerCancellationToken) => { result = await oapiClient.BlockAsync(slotValue, randaoRevealBytes, innerCancellationToken).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); BeaconNode.OApiClient.BeaconBlock oapiBeaconBlock = result !; Core2.Containers.BeaconBlock beaconBlock = new Core2.Containers.BeaconBlock( new Slot((ulong)oapiBeaconBlock.Slot), new Hash32(Bytes.FromHexString(oapiBeaconBlock.Parent_root)), new Hash32(Bytes.FromHexString(oapiBeaconBlock.State_root)), new Core2.Containers.BeaconBlockBody( new BlsSignature(oapiBeaconBlock.Body.Randao_reveal), new Eth1Data( new Hash32(oapiBeaconBlock.Body.Eth1_data.Deposit_root), (ulong)oapiBeaconBlock.Body.Eth1_data.Deposit_count, new Hash32(oapiBeaconBlock.Body.Eth1_data.Block_hash) ), new Bytes32(oapiBeaconBlock.Body.Graffiti), oapiBeaconBlock.Body.Proposer_slashings.Select(x => new ProposerSlashing( new ValidatorIndex((ulong)x.Proposer_index), MapBeaconBlockHeader(x.Header_1), MapBeaconBlockHeader(x.Header_2) )), oapiBeaconBlock.Body.Attester_slashings.Select(x => new AttesterSlashing( MapIndexedAttestation(x.Attestation_1), MapIndexedAttestation(x.Attestation_2) )), oapiBeaconBlock.Body.Attestations.Select(x => new Core2.Containers.Attestation( new BitArray(x.Aggregation_bits), MapAttestationData(x.Data), new BlsSignature(x.Signature) ) ), oapiBeaconBlock.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) ) ) ), oapiBeaconBlock.Body.Voluntary_exits.Select(x => new VoluntaryExit( new Epoch((ulong)x.Epoch), new ValidatorIndex((ulong)x.Validator_index), new BlsSignature((x.Signature)) ) ) ), BlsSignature.Empty ); return(beaconBlock); }