Example #1
0
        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));
        }
Example #2
0
        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();
                }
            }
        }
Example #4
0
        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);
        }
Example #5
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 #6
0
        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);
        }