public async Task <ApiResponse <BeaconBlock> > NewBlockAsync(Slot slot, BlsSignature randaoReveal, CancellationToken cancellationToken) { string baseUri = "validator/block"; Dictionary <string, string> queryParameters = new Dictionary <string, string> { ["slot"] = slot.ToString(), ["randao_reveal"] = randaoReveal.ToString() }; string uri = QueryHelpers.AddQueryString(baseUri, queryParameters); using HttpResponseMessage httpResponse = await _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken); int statusCode = (int)httpResponse.StatusCode; if (statusCode == (int)StatusCode.InvalidRequest || statusCode == (int)StatusCode.CurrentlySyncing) { return(ApiResponse.Create <BeaconBlock>((StatusCode)statusCode)); } httpResponse.EnsureSuccessStatusCode(); // throws if not 200-299 await using Stream contentStream = await httpResponse.Content.ReadAsStreamAsync(); BeaconBlock content = await JsonSerializer.DeserializeAsync <BeaconBlock>(contentStream, _jsonSerializerOptions, cancellationToken); return(ApiResponse.Create((StatusCode)statusCode, content)); }
public async Task BasicNewBlock() { // Arrange int numberOfValidators = 64; int genesisTime = 1578009600; IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true); IConfigurationRoot configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string> { ["QuickStart:ValidatorCount"] = $"{numberOfValidators}", ["QuickStart:GenesisTime"] = $"{genesisTime}" }) .Build(); testServiceCollection.AddBeaconNodeQuickStart(configuration); testServiceCollection.AddBeaconNodeEth1Bridge(configuration); testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>()); ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider(); Eth1BridgeWorker eth1BridgeWorker = testServiceProvider.GetServices <IHostedService>().OfType <Eth1BridgeWorker>().First(); await eth1BridgeWorker.ExecuteEth1GenesisAsync(CancellationToken.None); IBeaconNodeApi beaconNode = testServiceProvider.GetService <IBeaconNodeApi>(); ApiResponse <Fork> forkResponse = await beaconNode.GetNodeForkAsync(CancellationToken.None); Fork fork = forkResponse.Content; fork.CurrentVersion.ShouldBe(new ForkVersion(new byte[4] { 0x00, 0x00, 0x00, 0x01 })); // Act BlockProducer blockProducer = testServiceProvider.GetService <BlockProducer>(); Slot targetSlot = new Slot(1); // With QuickStart64, proposer for Slot 1 is validator index 29, 0xa98ed496... QuickStartMockEth1GenesisProvider quickStartMockEth1GenesisProvider = (QuickStartMockEth1GenesisProvider)testServiceProvider.GetService <IEth1GenesisProvider>(); byte[] privateKey = quickStartMockEth1GenesisProvider.GeneratePrivateKey(29); BlsSignature randaoReveal = GetEpochSignature(testServiceProvider, privateKey, fork.CurrentVersion, targetSlot); // value for quickstart 20/64, fork 0, slot 1 randaoReveal.ToString().StartsWith("0x932f8730"); BeaconBlock newBlock = await blockProducer.NewBlockAsync(targetSlot, randaoReveal, CancellationToken.None); // Assert newBlock.Slot.ShouldBe(targetSlot); newBlock.Body.RandaoReveal.ShouldBe(randaoReveal); newBlock.ParentRoot.ToString().ShouldStartWith("0x4d4e9a16"); newBlock.Body.Eth1Data.DepositCount.ShouldBe((ulong)numberOfValidators); newBlock.Body.Eth1Data.DepositRoot.ToString().ShouldStartWith("0x66687aad"); newBlock.StateRoot.ToString().ShouldStartWith("0x0138b69f"); newBlock.Body.Attestations.Count.ShouldBe(0); newBlock.Body.Deposits.Count.ShouldBe(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(); } } }
public async Task BasicNewBlock() { // Arrange int numberOfValidators = 64; int genesisTime = 1578009600; IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true); IConfigurationRoot configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string> { ["QuickStart:ValidatorCount"] = $"{numberOfValidators}", ["QuickStart:GenesisTime"] = $"{genesisTime}" }) .Build(); testServiceCollection.AddBeaconNodeQuickStart(configuration); testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>()); ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider(); QuickStart quickStart = (QuickStart)testServiceProvider.GetService <INodeStart>(); await quickStart.InitializeNodeAsync(); IBeaconNodeApi beaconNode = testServiceProvider.GetService <IBeaconNodeApi>(); Core2.Containers.Fork fork = await beaconNode.GetNodeForkAsync(CancellationToken.None); fork.CurrentVersion.ShouldBe(new ForkVersion()); // Act BlockProducer blockProducer = testServiceProvider.GetService <BlockProducer>(); Slot targetSlot = new Slot(1); // With QuickStart64, proposer for Slot 1 is validator index 20, 0xa1c76af1... byte[] privateKey = quickStart.GeneratePrivateKey(20); BlsSignature randaoReveal = GetEpochSignature(testServiceProvider, privateKey, fork.CurrentVersion, targetSlot); // value for quickstart 20/64, fork 0, slot 1 randaoReveal.ToString().ShouldBe("0xa3426b6391a29c88f2280428d5fdae9e20f4c75a8d38d0714e3aa5b9e55594dbd555c4bc685191e83d39158c3be9744d06adc34b21d2885998a206e3b3fd435eab424cf1c01b8fd562deb411348a601e83d7332d8774d1fd3bf8b88d7a33c67c"); BeaconBlock newBlock = await blockProducer.NewBlockAsync(targetSlot, randaoReveal); // Assert newBlock.Slot.ShouldBe(targetSlot); newBlock.Body.RandaoReveal.ShouldBe(randaoReveal); Hash32 expectedParentRoot = new Hash32("0x91b06cbcd6dc97b89dc8b95e0b01a497932683b182e6c722ddfa10cd005b2180"); newBlock.ParentRoot.ShouldBe(expectedParentRoot); newBlock.Body.Eth1Data.DepositCount.ShouldBe((ulong)numberOfValidators); Hash32 expectedEth1DataDepositRoot = new Hash32("0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925"); newBlock.Body.Eth1Data.DepositRoot.ShouldBe(expectedEth1DataDepositRoot); Hash32 expectedStateRoot = new Hash32("0xe05ccf6347cac0b0dab0ad0d5c941fe7c7e2ed4c69550ed9a628bc9d62914242"); newBlock.StateRoot.ShouldBe(expectedStateRoot); newBlock.Signature.ShouldBe(new BlsSignature(new byte[96])); // signature should be empty newBlock.Body.Attestations.Count.ShouldBe(0); newBlock.Body.Deposits.Count.ShouldBe(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); } }
public async Task BasicNewBlock() { // Arrange int numberOfValidators = 64; int genesisTime = 1578009600; IServiceCollection testServiceCollection = TestSystem.BuildTestServiceCollection(useStore: true); IConfigurationRoot configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary <string, string> { ["QuickStart:ValidatorCount"] = $"{numberOfValidators}", ["QuickStart:GenesisTime"] = $"{genesisTime}" }) .Build(); testServiceCollection.AddQuickStart(configuration); testServiceCollection.AddSingleton <IHostEnvironment>(Substitute.For <IHostEnvironment>()); ServiceProvider testServiceProvider = testServiceCollection.BuildServiceProvider(); QuickStart quickStart = (QuickStart)testServiceProvider.GetService <INodeStart>(); await quickStart.InitializeNodeAsync(); IBeaconNodeApi beaconNode = testServiceProvider.GetService <IBeaconNodeApi>(); Core2.Containers.Fork fork = await beaconNode.GetNodeForkAsync(); fork.CurrentVersion.ShouldBe(new ForkVersion()); // Act BlockProducer blockProducer = testServiceProvider.GetService <BlockProducer>(); Slot targetSlot = new Slot(1); // With QuickStart64, proposer for Slot 1 is validator index 20, 0xa1c76af1... byte[] privateKey = quickStart.GeneratePrivateKey(20); BlsSignature randaoReveal = GetEpochSignature(testServiceProvider, privateKey, fork.CurrentVersion, targetSlot); // value for quickstart 20/64, fork 0, slot 1 randaoReveal.ToString().ShouldBe("0xa3426b6391a29c88f2280428d5fdae9e20f4c75a8d38d0714e3aa5b9e55594dbd555c4bc685191e83d39158c3be9744d06adc34b21d2885998a206e3b3fd435eab424cf1c01b8fd562deb411348a601e83d7332d8774d1fd3bf8b88d7a33c67c"); BeaconBlock newBlock = await blockProducer.NewBlockAsync(targetSlot, randaoReveal); // Assert newBlock.Slot.ShouldBe(targetSlot); newBlock.Body.RandaoReveal.ShouldBe(randaoReveal); Hash32 expectedParentRoot = new Hash32(Bytes.FromHexString("0x3111350140726cc0501223143ae5c7baad7f5a06764fcc7d444a657016e7d616")); newBlock.ParentRoot.ShouldBe(expectedParentRoot); newBlock.Body.Eth1Data.DepositCount.ShouldBe((ulong)numberOfValidators); Hash32 expectedEth1DataDepositRoot = new Hash32(Bytes.FromHexString("0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925")); newBlock.Body.Eth1Data.DepositRoot.ShouldBe(expectedEth1DataDepositRoot); Hash32 expectedStateRoot = new Hash32(Bytes.FromHexString("0x9c7d3e5180f95175691511fd56f8a610299f0b5a682b6fe178230493d74f6d13")); newBlock.StateRoot.ShouldBe(expectedStateRoot); newBlock.Signature.ShouldBe(new BlsSignature(new byte[96])); // signature should be empty newBlock.Body.Attestations.Count.ShouldBe(0); newBlock.Body.Deposits.Count.ShouldBe(0); }