Esempio n. 1
0
        public void Beacon_block_body_there_and_back()
        {
            Eth1Data eth1Data = new Eth1Data(
                Sha256.OfAnEmptyString,
                1,
                Sha256.OfAnEmptyString);

            BeaconBlockBody container = new BeaconBlockBody(
                SszTest.TestSig1,
                eth1Data,
                new Bytes32(new byte[32]),
                new ProposerSlashing[2],
                new AttesterSlashing[3],
                new Attestation[4],
                new Deposit[5],
                new VoluntaryExit[6]
                );

            Span <byte> encoded = new byte[Ssz.BeaconBlockBodyLength(container)];

            Ssz.Encode(encoded, container);
            BeaconBlockBody decoded = Ssz.DecodeBeaconBlockBody(encoded);

            AssertBeaconBlockBodyEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
Esempio n. 2
0
        public void Beacon_block_body_there_and_back()
        {
            Eth1Data eth1Data = new Eth1Data();

            eth1Data.BlockHash    = Sha256.OfAnEmptyString;
            eth1Data.DepositCount = 1;
            eth1Data.DepositRoot  = Sha256.OfAnEmptyString;

            BeaconBlockBody container = new BeaconBlockBody();

            container.RandaoReversal    = BlsSignature.TestSig1;
            container.Eth1Data          = eth1Data;
            container.Graffiti          = new byte[32];
            container.ProposerSlashings = new ProposerSlashing[2];
            container.AttesterSlashings = new AttesterSlashing[3];
            container.Attestations      = new Attestation[4];
            container.Deposits          = new Deposit[5];
            container.VoluntaryExits    = new VoluntaryExit[6];

            Span <byte> encoded = new byte[BeaconBlockBody.SszLength(container)];

            Ssz.Encode(encoded, container);
            BeaconBlockBody decoded = Ssz.DecodeBeaconBlockBody(encoded);

            Assert.AreEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
Esempio n. 3
0
        public void Beacon_block_body_there_and_back()
        {
            Eth1Data eth1Data = new Eth1Data(
                Sha256.RootOfAnEmptyString,
                1,
                Sha256.Bytes32OfAnEmptyString);

            Deposit         zeroDeposit = new Deposit(Enumerable.Repeat(Bytes32.Zero, Ssz.DepositContractTreeDepth + 1), DepositData.Zero);
            BeaconBlockBody container   = new BeaconBlockBody(
                TestSig1,
                eth1Data,
                new Bytes32(new byte[32]),
                Enumerable.Repeat(ProposerSlashing.Zero, 2).ToArray(),
                Enumerable.Repeat(AttesterSlashing.Zero, 3).ToArray(),
                Enumerable.Repeat(Attestation.Zero, 4).ToArray(),
                Enumerable.Repeat(zeroDeposit, 5).ToArray(),
                Enumerable.Repeat(SignedVoluntaryExit.Zero, 6).ToArray()
                );

            Span <byte> encoded = new byte[Ssz.BeaconBlockBodyLength(container)];

            Ssz.Encode(encoded, container);
            BeaconBlockBody decoded = Ssz.DecodeBeaconBlockBody(encoded);

            AssertBeaconBlockBodyEqual(container, decoded);

            Merkle.Ize(out UInt256 root, container);
        }
Esempio n. 4
0
        public static BeaconBlockBody DecodeBeaconBlockBody(Span <byte> span)
        {
            // static part

            int             offset    = 0;
            BeaconBlockBody container = new BeaconBlockBody();

            container.RandaoReversal = DecodeBlsSignature(span, ref offset);
            container.Eth1Data       = DecodeEth1Data(span, ref offset);
            container.Graffiti       = DecodeBytes32(span, ref offset);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset1);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset2);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset3);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset4);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset5);

            // var part

            int proposerSlashingsLength = dynamicOffset2 - dynamicOffset1;
            int attesterSlashingsLength = dynamicOffset3 - dynamicOffset2;
            int attestationsLength      = dynamicOffset4 - dynamicOffset3;
            int depositsLength          = dynamicOffset5 - dynamicOffset4;
            int voluntaryExitsLength    = span.Length - dynamicOffset5;

            container.ProposerSlashings = DecodeProposerSlashings(span.Slice(dynamicOffset1, proposerSlashingsLength));
            container.AttesterSlashings = DecodeAttesterSlashings(span.Slice(dynamicOffset2, attesterSlashingsLength));
            container.Attestations      = DecodeAttestations(span.Slice(dynamicOffset3, attestationsLength));
            container.Deposits          = DecodeDeposits(span.Slice(dynamicOffset4, depositsLength));
            container.VoluntaryExits    = DecodeVoluntaryExits(span.Slice(dynamicOffset5, voluntaryExitsLength));

            return(container);
        }
Esempio n. 5
0
        public void ProcessOperations(BeaconState state, BeaconBlockBody body)
        {
            _logger.LogInformation(Event.ProcessOperations, "Process block operations for block body {BeaconBlockBody}", body);
            // Verify that outstanding deposits are processed up to the maximum number of deposits
            var outstandingDeposits = state.Eth1Data.DepositCount - state.Eth1DepositIndex;
            var expectedDeposits    = Math.Min(_maxOperationsPerBlockOptions.CurrentValue.MaximumDeposits, outstandingDeposits);

            if (body.Deposits.Count != (int)expectedDeposits)
            {
                throw new ArgumentOutOfRangeException("body.Deposits.Count", body.Deposits.Count, $"Block body does not have the expected number of outstanding deposits {expectedDeposits}.");
            }

            foreach (var proposerSlashing in body.ProposerSlashings)
            {
                ProcessProposerSlashing(state, proposerSlashing);
            }
            foreach (var attesterSlashing in body.AttesterSlashings)
            {
                ProcessAttesterSlashing(state, attesterSlashing);
            }
            foreach (var attestation in body.Attestations)
            {
                ProcessAttestation(state, attestation);
            }
            foreach (var deposit in body.Deposits)
            {
                ProcessDeposit(state, deposit);
            }
            foreach (var voluntaryExit in body.VoluntaryExits)
            {
                ProcessVoluntaryExit(state, voluntaryExit);
            }
            //ProcessShareReceiptProof();
        }
        public void EmptyBeaconBlockBodyDecode()
        {
            // Arrange
            string hex =
                // static
                "565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656" +
                "1212121212121212121212121212121212121212121212121212121212121212" +
                "4000000000000000" +
                "3434343434343434343434343434343434343434343434343434343434343434" +
                "7878787878787878787878787878787878787878787878787878787878787878" +
                "dc000000" + // proposer dynamic offset 96+(32+8+32)+32 + 5*4 = 220 = 0xdc
                "dc000000" + // attester slashings & all remaining offsets are the same, as they are empty
                "dc000000" +
                "dc000000" +
                "dc000000"; // dynamic part is empty

            byte[] bytes = Bytes.FromHexString(hex);

            // Act
            BeaconBlockBody beaconBlockBody = Ssz.DecodeBeaconBlockBody(bytes);

            // Assert
            beaconBlockBody.RandaoReveal.AsSpan().ToArray().ShouldBe(Enumerable.Repeat((byte)0x56, 96).ToArray());
            beaconBlockBody.Eth1Data.DepositRoot.AsSpan().ToArray().ShouldBe(Enumerable.Repeat((byte)0x12, 32).ToArray());
            beaconBlockBody.Eth1Data.DepositCount.ShouldBe(64uL);
            beaconBlockBody.Eth1Data.BlockHash.AsSpan().ToArray().ShouldBe(Enumerable.Repeat((byte)0x34, 32).ToArray());
            beaconBlockBody.Graffiti.AsSpan().ToArray().ShouldBe(Enumerable.Repeat((byte)0x78, 32).ToArray());
            beaconBlockBody.ProposerSlashings.Count.ShouldBe(0);
            beaconBlockBody.AttesterSlashings.Count.ShouldBe(0);
            beaconBlockBody.Attestations.Count.ShouldBe(0);
            beaconBlockBody.Deposits.Count.ShouldBe(0);
            beaconBlockBody.VoluntaryExits.Count.ShouldBe(0);
        }
Esempio n. 7
0
 public BeaconBlock(Hash32 genesisStateRoot)
 {
     Slot       = new Slot(0);
     ParentRoot = Hash32.Zero;
     StateRoot  = genesisStateRoot;
     Body       = new BeaconBlockBody();
     Signature  = new BlsSignature();
 }
        public Root HashTreeRoot(BeaconBlockBody beaconBlockBody)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            MaxOperationsPerBlock   maxOperationsPerBlock   = _maxOperationsPerBlockOptions.CurrentValue;

            return(beaconBlockBody.HashTreeRoot(maxOperationsPerBlock.MaximumProposerSlashings,
                                                maxOperationsPerBlock.MaximumAttesterSlashings, maxOperationsPerBlock.MaximumAttestations,
                                                maxOperationsPerBlock.MaximumDeposits, maxOperationsPerBlock.MaximumVoluntaryExits,
                                                miscellaneousParameters.MaximumValidatorsPerCommittee));
        }
Esempio n. 9
0
 public BeaconBlock(Slot slot, Hash32 parentRoot, Hash32 stateRoot, BeaconBlockBody body, BlsSignature signature)
 {
     Slot       = slot;
     ParentRoot = parentRoot;
     StateRoot  = stateRoot;
     Body       = body;
     Signature  = signature;
     //Body = new BeaconBlockBody(randaoReveal,
     //    new Eth1Data(Hash32.Zero, 0),
     //    new Bytes32(), Array.Empty<Deposit>());
 }
Esempio n. 10
0
        private static void TestBeaconBlockBodySsz(byte[] serialized, UInt256 expectedMerkleRoot, string testCaseDir)
        {
            BeaconBlockBody container = Nethermind.Ssz.Ssz.DecodeBeaconBlockBody(serialized);

            byte[] again = new byte[serialized.Length];
            Nethermind.Ssz.Ssz.Encode(again, container);
            Assert.AreEqual(serialized.ToHexString(), again.ToHexString(), testCaseDir);

            Merkle.Ize(out UInt256 root, container);
            Assert.AreEqual(expectedMerkleRoot, root);
        }
        public void CheckEmptyBlockRootAfterDeserializing()
        {
            // Arrange

            Eth1Data eth1Data = new Eth1Data(
                new Root(Enumerable.Repeat((byte)0x12, 32).ToArray()),
                64,
                new Bytes32(Enumerable.Repeat((byte)0x34, 32).ToArray()));

            BlsSignature randaoReveal = new BlsSignature(Enumerable.Repeat((byte)0xfe, 96).ToArray());

            BeaconBlockBody beaconBlockBody = new BeaconBlockBody(
                randaoReveal,
                eth1Data,
                new Bytes32(new byte[32]),
                new ProposerSlashing[0],
                new AttesterSlashing [0],
                new Attestation[0],
                new Deposit[0],
                new SignedVoluntaryExit[0]
                );

            BeaconBlock beaconBlock = new BeaconBlock(
                new Slot(1),
                new Root(Enumerable.Repeat((byte)0x78, 32).ToArray()),
                new Root(Enumerable.Repeat((byte)0x9a, 32).ToArray()),
                beaconBlockBody);

            Merkle.Ize(out UInt256 blockRoot256, beaconBlock);
            Span <byte> blockRootSpan = MemoryMarshal.Cast <UInt256, byte>(MemoryMarshal.CreateSpan(ref blockRoot256, 1));
            Root        blockRoot     = new Root(blockRootSpan);

            SignedBeaconBlock signedBeaconBlock = new SignedBeaconBlock(
                beaconBlock,
                new BlsSignature(Enumerable.Repeat((byte)0x0e, 96).ToArray())
                );

            // Act

            Span <byte> encoded = new byte[Ssz.SignedBeaconBlockLength(signedBeaconBlock)];

            Ssz.Encode(encoded, signedBeaconBlock);

            SignedBeaconBlock decoded = Ssz.DecodeSignedBeaconBlock(encoded);

            // Assert

            Merkle.Ize(out UInt256 decodedBlockRoot256, decoded.Message);
            Span <byte> decodedBlockRootSpan = MemoryMarshal.Cast <UInt256, byte>(MemoryMarshal.CreateSpan(ref decodedBlockRoot256, 1));
            Root        decodedBlockRoot     = new Root(decodedBlockRootSpan);

            decodedBlockRoot.ShouldBe(blockRoot);
        }
Esempio n. 12
0
        public void ProcessEth1Data(BeaconState state, BeaconBlockBody body)
        {
            _logger.LogInformation(Event.ProcessEth1Data, "Process block ETH1 data for block body {BeaconBlockBody}", body);

            state.AddEth1DataVote(body.Eth1Data);
            var eth1DataVoteCount = state.Eth1DataVotes.Count(x => x.Equals(body.Eth1Data));

            if (eth1DataVoteCount * 2 > (int)(ulong)_timeParameterOptions.CurrentValue.SlotsPerEth1VotingPeriod)
            {
                state.SetEth1Data(body.Eth1Data);
            }
        }
Esempio n. 13
0
        public async Task SignedBeaconBlock_RoundTripEmpty()
        {
            // Arrange
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.ConfigureNethermindCore2();

            Eth1Data eth1Data = new Eth1Data(
                new Root(Enumerable.Repeat((byte)0x12, 32).ToArray()),
                64,
                new Bytes32(Enumerable.Repeat((byte)0x34, 32).ToArray()));

            BlsSignature randaoReveal = new BlsSignature(Enumerable.Repeat((byte)0xfe, 96).ToArray());

            BeaconBlockBody beaconBlockBody = new BeaconBlockBody(
                randaoReveal,
                eth1Data,
                new Bytes32(new byte[32]),
                new ProposerSlashing[0],
                new AttesterSlashing [0],
                new Attestation[0],
                new Deposit[0],
                new SignedVoluntaryExit[0]
                );

            BeaconBlock beaconBlock = new BeaconBlock(
                new Slot(1),
                new Root(Enumerable.Repeat((byte)0x78, 32).ToArray()),
                new Root(Enumerable.Repeat((byte)0x9a, 32).ToArray()),
                beaconBlockBody);

            SignedBeaconBlock signedBeaconBlock = new SignedBeaconBlock(
                beaconBlock,
                new BlsSignature(Enumerable.Repeat((byte)0x0e, 96).ToArray())
                );

            // Act - round trip to string
            await using MemoryStream outputMemoryStream = new MemoryStream();
            await JsonSerializer.SerializeAsync(outputMemoryStream, signedBeaconBlock, options);

            string jsonString = Encoding.UTF8.GetString(outputMemoryStream.ToArray());

            Console.WriteLine(jsonString);

            // Assert - Round trip

            await using MemoryStream inputMemoryStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
            SignedBeaconBlock roundTripSignedBeaconBlock = await JsonSerializer.DeserializeAsync <SignedBeaconBlock>(inputMemoryStream, options);

            roundTripSignedBeaconBlock.Message.Body.Eth1Data.BlockHash.AsSpan()[1].ShouldBe((byte)0x34);
        }
Esempio n. 14
0
        public void EmptyBeaconBlockEncode()
        {
            // Arrange
            Eth1Data eth1Data = new Eth1Data(
                new Root(Enumerable.Repeat((byte)0x12, 32).ToArray()),
                64,
                new Bytes32(Enumerable.Repeat((byte)0x34, 32).ToArray()));
            BeaconBlockBody beaconBlockBody = new BeaconBlockBody(
                new BlsSignature(Enumerable.Repeat((byte)0x56, 96).ToArray()),
                eth1Data,
                new Bytes32(Enumerable.Repeat((byte)0x78, 32).ToArray()),
                new ProposerSlashing[0],
                new AttesterSlashing [0],
                new Attestation[0],
                new Deposit[0],
                new SignedVoluntaryExit[0]
                );
            BeaconBlock beaconBlock = new BeaconBlock(
                Slot.One,
                new Root(Enumerable.Repeat((byte)0x9a, 32).ToArray()),
                new Root(Enumerable.Repeat((byte)0xbc, 32).ToArray()),
                beaconBlockBody
                );

            // Act
            Span <byte> encoded = new byte[Ssz.BeaconBlockLength(beaconBlock)];

            Ssz.Encode(encoded, beaconBlock);

            // Assert
            string expectedHex =
                // static
                "0100000000000000" +
                "9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a" +
                "bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc" +
                "4c000000" + // body dynamic offset 8+32+32+4 = 76 = 0x4c
                // dynamic
                // - body - static
                "565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656" +
                "1212121212121212121212121212121212121212121212121212121212121212" +
                "4000000000000000" +
                "3434343434343434343434343434343434343434343434343434343434343434" +
                "7878787878787878787878787878787878787878787878787878787878787878" +
                "dc000000" + // proposer dynamic offset 96+(32+8+32)+32 + 5*4 = 220 = 0xdc
                "dc000000" + // attester slashings & all remaining offsets are the same, as they are empty
                "dc000000" +
                "dc000000" +
                "dc000000"; // body - dynamic part is empty

            encoded.ToHexString().ShouldBe(expectedHex);
        }
Esempio n. 15
0
        public static void Ize(out UInt256 root, BeaconBlockBody container)
        {
            Merkleizer merkleizer = new Merkleizer(3);

            merkleizer.Feed(container.RandaoReversal);
            merkleizer.Feed(container.Eth1Data);
            merkleizer.Feed(container.Graffiti);
            merkleizer.Feed(container.ProposerSlashings, BeaconBlock.MaxProposerSlashings);
            merkleizer.Feed(container.AttesterSlashings, BeaconBlock.MaxAttesterSlashings);
            merkleizer.Feed(container.Attestations, BeaconBlock.MaxAttestations);
            merkleizer.Feed(container.Deposits, BeaconBlock.MaxDeposits);
            merkleizer.Feed(container.VoluntaryExits, BeaconBlock.MaxVoluntaryExits);
            merkleizer.CalculateRoot(out root);
        }
Esempio n. 16
0
        public static void Encode(Span <byte> span, BeaconBlockBody container)
        {
            int offset        = 0;
            int dynamicOffset = BeaconBlockBody.SszDynamicOffset;

            Encode(span, container.RandaoReversal, ref offset);
            Encode(span, container.Eth1Data, ref offset);
            Encode(span, container.Graffiti, ref offset);
            Encode(span, container.ProposerSlashings, ref offset, ref dynamicOffset);
            Encode(span, container.AttesterSlashings, ref offset, ref dynamicOffset);
            Encode(span, container.Attestations, ref offset, ref dynamicOffset);
            Encode(span, container.Deposits, ref offset, ref dynamicOffset);
            Encode(span, container.VoluntaryExits, ref offset, ref dynamicOffset);
        }
Esempio n. 17
0
        public BeaconState InitializeBeaconStateFromEth1(Hash32 eth1BlockHash, ulong eth1Timestamp, IEnumerable <Deposit> deposits)
        {
            if (_logger.IsInfo())
            {
                Log.InitializeBeaconState(_logger, eth1BlockHash, eth1Timestamp, deposits.Count(), null);
            }

            GweiValues       gweiValues       = _gweiValueOptions.CurrentValue;
            InitialValues    initialValues    = _initialValueOptions.CurrentValue;
            TimeParameters   timeParameters   = _timeParameterOptions.CurrentValue;
            StateListLengths stateListLengths = _stateListLengthOptions.CurrentValue;

            ulong genesisTime = eth1Timestamp - (eth1Timestamp % _chainConstants.SecondsPerDay)
                                + (2 * _chainConstants.SecondsPerDay);
            Eth1Data        eth1Data       = new Eth1Data((ulong)deposits.Count(), eth1BlockHash);
            BeaconBlockBody emptyBlockBody = new BeaconBlockBody();

            Hash32 emptyBlockBodyRoot = _cryptographyService.HashTreeRoot(emptyBlockBody);

            BeaconBlockHeader latestBlockHeader = new BeaconBlockHeader(emptyBlockBodyRoot);
            BeaconState       state             = new BeaconState(genesisTime, 0, eth1Data, latestBlockHeader, timeParameters.SlotsPerHistoricalRoot, stateListLengths.EpochsPerHistoricalVector, stateListLengths.EpochsPerSlashingsVector, _chainConstants.JustificationBitsLength);

            // Process deposits
            List <DepositData> depositDataList = new List <DepositData>();

            foreach (Deposit deposit in deposits)
            {
                depositDataList.Add(deposit.Data);
                Hash32 depositRoot = _cryptographyService.HashTreeRoot(depositDataList);
                state.Eth1Data.SetDepositRoot(depositRoot);
                _beaconStateTransition.ProcessDeposit(state, deposit);
            }

            // Process activations
            for (int validatorIndex = 0; validatorIndex < state.Validators.Count; validatorIndex++)
            {
                Validator validator        = state.Validators[validatorIndex];
                Gwei      balance          = state.Balances[validatorIndex];
                Gwei      effectiveBalance = Gwei.Min(balance - (balance % gweiValues.EffectiveBalanceIncrement), gweiValues.MaximumEffectiveBalance);
                validator.SetEffectiveBalance(effectiveBalance);
                if (validator.EffectiveBalance == gweiValues.MaximumEffectiveBalance)
                {
                    validator.SetEligible(initialValues.GenesisEpoch);
                    validator.SetActive(initialValues.GenesisEpoch);
                }
            }

            return(state);
        }
Esempio n. 18
0
        public Hash32 HashTreeRoot(BeaconBlockBody beaconBlockBody)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            MaxOperationsPerBlock maxOperationsPerBlock = _maxOperationsPerBlockOptions.CurrentValue;
            return beaconBlockBody.HashTreeRoot(maxOperationsPerBlock.MaximumProposerSlashings,
                maxOperationsPerBlock.MaximumAttesterSlashings, maxOperationsPerBlock.MaximumAttestations,
                maxOperationsPerBlock.MaximumDeposits, maxOperationsPerBlock.MaximumVoluntaryExits,
                miscellaneousParameters.MaximumValidatorsPerCommittee);
            
            // TODO: Get this working and switch over block body, beacon block, and state

//            Merkle.Ize(out UInt256 root, beaconBlockBody);
//            Span<byte> bytes = MemoryMarshal.Cast<UInt256, byte>(MemoryMarshal.CreateSpan(ref root, 1));
//            return new Hash32(bytes);
        }
Esempio n. 19
0
        private static void Encode(Span <byte> span, BeaconBlockBody container, ref int offset)
        {
            // Semantics of Encode = write container into span at offset, then increase offset by the bytes written

            // Static
            int dynamicOffset = Ssz.BeaconBlockBodyDynamicOffset;

            Encode(span, container.RandaoReveal, ref offset);
            Encode(span, container.Eth1Data, ref offset);
            Encode(span, container.Graffiti.AsSpan().ToArray(), ref offset);

            Encode(span, dynamicOffset, ref offset);
            int proposerSlashingsLength = container.ProposerSlashings.Count * Ssz.ProposerSlashingLength;

            dynamicOffset += proposerSlashingsLength;

            Encode(span, dynamicOffset, ref offset);
            int attesterSlashingsLength = container.AttesterSlashings.Sum(x => Ssz.AttesterSlashingLength(x) + VarOffsetSize);

            dynamicOffset += attesterSlashingsLength;

            Encode(span, dynamicOffset, ref offset);
            dynamicOffset += container.Attestations.Sum(x => Ssz.AttestationLength(x) + VarOffsetSize);

            Encode(span, dynamicOffset, ref offset);
            int depositsLength = container.Deposits.Count * Ssz.DepositLength();

            dynamicOffset += depositsLength;

            Encode(span, dynamicOffset, ref offset);
            int voluntaryExitsLength = container.VoluntaryExits.Count * Ssz.VoluntaryExitLength;

            dynamicOffset += voluntaryExitsLength;

            // Dynamic
            Encode(span.Slice(offset, proposerSlashingsLength), container.ProposerSlashings.ToArray());
            offset += proposerSlashingsLength;

            Encode(span.Slice(offset, attesterSlashingsLength), container.AttesterSlashings.ToArray());
            offset += attesterSlashingsLength;

            Encode(span, container.Attestations, ref offset);

            Encode(span.Slice(offset, depositsLength), container.Deposits.ToArray());
            offset += depositsLength;

            EncodeList(span, container.VoluntaryExits, ref offset);
        }
Esempio n. 20
0
        private void AssertBeaconBlockBodyEqual(BeaconBlockBody expected, BeaconBlockBody actual)
        {
            actual.RandaoReveal.ShouldBe(expected.RandaoReveal);
            actual.Eth1Data.ShouldBe(expected.Eth1Data);
            actual.Graffiti.ShouldBe(expected.Graffiti);
            actual.ProposerSlashings.Count.ShouldBe(expected.ProposerSlashings.Count);
            actual.AttesterSlashings.Count.ShouldBe(expected.AttesterSlashings.Count);
            actual.Attestations.Count.ShouldBe(expected.Attestations.Count);
            actual.Deposits.Count.ShouldBe(expected.Deposits.Count);
            actual.VoluntaryExits.Count.ShouldBe(expected.VoluntaryExits.Count);

            actual.AttesterSlashings.ShouldBe(expected.AttesterSlashings);
            actual.ProposerSlashings.ShouldBe(expected.ProposerSlashings);
            actual.Attestations.ShouldBe(expected.Attestations);
            actual.Deposits.ShouldBe(expected.Deposits);
            actual.VoluntaryExits.ShouldBe(expected.VoluntaryExits);
        }
Esempio n. 21
0
        public BeaconState InitializeBeaconStateFromEth1(Hash32 eth1BlockHash, ulong eth1Timestamp, IEnumerable <Deposit> deposits)
        {
            _logger.LogDebug(Event.InitializeBeaconState, "Initialise beacon state from ETH1 block {Eth1BlockHash}, time {Eth1Timestamp}, with {DepositCount} deposits.", eth1BlockHash, eth1Timestamp, deposits.Count());

            var gweiValues       = _gweiValueOptions.CurrentValue;
            var initialValues    = _initialValueOptions.CurrentValue;
            var timeParameters   = _timeParameterOptions.CurrentValue;
            var stateListLengths = _stateListLengthOptions.CurrentValue;

            var genesisTime = eth1Timestamp - (eth1Timestamp % _chainConstants.SecondsPerDay)
                              + (2 * _chainConstants.SecondsPerDay);
            var eth1Data          = new Eth1Data((ulong)deposits.Count(), eth1BlockHash);
            var emptyBlockBody    = new BeaconBlockBody();
            var latestBlockHeader = new BeaconBlockHeader(emptyBlockBody.HashTreeRoot(_miscellaneousParameterOptions.CurrentValue, _maxOperationsPerBlockOptions.CurrentValue));
            var state             = new BeaconState(genesisTime, 0, eth1Data, latestBlockHeader, timeParameters.SlotsPerHistoricalRoot, stateListLengths.EpochsPerHistoricalVector, stateListLengths.EpochsPerSlashingsVector, _chainConstants.JustificationBitsLength);

            // Process deposits
            var depositDataList = new List <DepositData>();

            foreach (var deposit in deposits)
            {
                depositDataList.Add(deposit.Data);
                var depositRoot = depositDataList.HashTreeRoot(_chainConstants.MaximumDepositContracts);
                state.Eth1Data.SetDepositRoot(depositRoot);
                _beaconStateTransition.ProcessDeposit(state, deposit);
            }

            // Process activations
            for (var validatorIndex = 0; validatorIndex < state.Validators.Count; validatorIndex++)
            {
                var validator        = state.Validators[validatorIndex];
                var balance          = state.Balances[validatorIndex];
                var effectiveBalance = Gwei.Min(balance - (balance % gweiValues.EffectiveBalanceIncrement), gweiValues.MaximumEffectiveBalance);
                validator.SetEffectiveBalance(effectiveBalance);
                if (validator.EffectiveBalance == gweiValues.MaximumEffectiveBalance)
                {
                    validator.SetEligible(initialValues.GenesisEpoch);
                    validator.SetActive(initialValues.GenesisEpoch);
                }
            }

            return(state);
        }
Esempio n. 22
0
        public async Task <BeaconBlock> NewBlockAsync(Slot slot, BlsSignature randaoReveal)
        {
            var store = _storeProvider.GetStore();

            if (store == null)
            {
                throw new Exception("Beacon chain is currently syncing or waiting for genesis.");
            }

            var head = await _forkChoice.GetHeadAsync(store);

            // get previous head block, based on the fork choice
            // get latest state
            // process outstanding slots for state
            // get parent header (state root, signature, slot, parent root, body root)

            var body = new BeaconBlockBody(randaoReveal,
                                           new Eth1Data(0, Hash32.Zero),
                                           new Bytes32(),
                                           Array.Empty <ProposerSlashing>(),
                                           Array.Empty <AttesterSlashing>(),
                                           Array.Empty <Attestation>(),
                                           Array.Empty <Deposit>(),
                                           Array.Empty <VoluntaryExit>());
            var block = new BeaconBlock(slot, Hash32.Zero, Hash32.Zero, body, new BlsSignature());

            // new block = slot, parent root,
            //  signature = null
            //  body = assemble body

            // assemble body:
            //  from opPool get proposer slashings, attester slashings, attestations, voluntary exits
            //  get eth1data
            // generate deposits (based on new data)
            //     -> if eth1data deposit count > state deposit index, then get from op pool, sort and calculate merkle tree
            // deposit root = merkleRoot
            // randaoReveal

            // apply block to state transition
            // block.stateRoot = new state hash

            return(await Task.Run(() => block));
        }
Esempio n. 23
0
        private static IEnumerable <SszElement> GetValues(BeaconBlockBody item, MiscellaneousParameters miscellaneousParameters, MaxOperationsPerBlock maxOperationsPerBlock)
        {
            yield return(item.RandaoReveal.ToSszBasicVector());

            yield return(item.Eth1Data.ToSszContainer());

            yield return(item.Graffiti.ToSszBasicVector());

            // Operations
            yield return(item.ProposerSlashings.ToSszList(maxOperationsPerBlock.MaximumProposerSlashings));

            yield return(item.AttesterSlashings.ToSszList(maxOperationsPerBlock.MaximumAttesterSlashings, miscellaneousParameters));

            yield return(item.Attestations.ToSszList(maxOperationsPerBlock.MaximumAttestations, miscellaneousParameters));

            yield return(item.Deposits.ToSszList(maxOperationsPerBlock.MaximumDeposits));

            yield return(item.VoluntaryExits.ToSszList(maxOperationsPerBlock.MaximumVoluntaryExits));
            //yield return item.Transfers.ToSszList(MAX_TRANSFERS);
        }
Esempio n. 24
0
        private static IEnumerable <SszElement> GetValues(BeaconBlockBody item, ulong maximumProposerSlashings, ulong maximumAttesterSlashings, ulong maximumAttestations, ulong maximumDeposits, ulong maximumVoluntaryExits, ulong maximumValidatorsPerCommittee)
        {
            yield return(item.RandaoReveal.ToSszBasicVector());

            yield return(item.Eth1Data.ToSszContainer());

            yield return(item.Graffiti.ToSszBasicVector());

            // Operations
            yield return(item.ProposerSlashings.ToSszList(maximumProposerSlashings));

            yield return(item.AttesterSlashings.ToSszList(maximumAttesterSlashings, maximumValidatorsPerCommittee));

            yield return(item.Attestations.ToSszList(maximumAttestations, maximumValidatorsPerCommittee));

            yield return(item.Deposits.ToSszList(maximumDeposits));

            yield return(item.VoluntaryExits.ToSszList(maximumVoluntaryExits));
            //yield return item.Transfers.ToSszList(MAX_TRANSFERS);
        }
Esempio n. 25
0
        public void Beacon_block_there_and_back()
        {
            Eth1Data eth1Data = new Eth1Data();

            eth1Data.BlockHash    = Sha256.OfAnEmptyString;
            eth1Data.DepositCount = 1;
            eth1Data.DepositRoot  = Sha256.OfAnEmptyString;

            BeaconBlockBody beaconBlockBody = new BeaconBlockBody();

            beaconBlockBody.RandaoReversal    = BlsSignature.TestSig1;
            beaconBlockBody.Eth1Data          = eth1Data;
            beaconBlockBody.Graffiti          = new byte[32];
            beaconBlockBody.ProposerSlashings = new ProposerSlashing[2];
            beaconBlockBody.AttesterSlashings = new AttesterSlashing[3];
            beaconBlockBody.Attestations      = new Attestation[4];
            beaconBlockBody.Deposits          = new Deposit[5];
            beaconBlockBody.VoluntaryExits    = new VoluntaryExit[6];

            BeaconBlock container = new BeaconBlock();

            container.Body       = beaconBlockBody;
            container.Signature  = BlsSignature.TestSig1;
            container.Slot       = new Slot(1);
            container.ParentRoot = Sha256.OfAnEmptyString;
            container.StateRoot  = Sha256.OfAnEmptyString;

            Span <byte> encoded = new byte[BeaconBlock.SszLength(container)];

            Ssz.Encode(encoded, container);
            BeaconBlock decoded = Ssz.DecodeBeaconBlock(encoded);

            Assert.AreEqual(container, decoded);

            Span <byte> encodedAgain = new byte[BeaconBlock.SszLength(container)];

            Ssz.Encode(encodedAgain, decoded);
            Assert.True(Bytes.AreEqual(encodedAgain, encoded));

            Merkle.Ize(out UInt256 root, container);
        }
Esempio n. 26
0
        public static BeaconBlockBody DecodeBeaconBlockBody(Span <byte> span)
        {
            // static part

            int          offset       = 0;
            BlsSignature randaoReveal = DecodeBlsSignature(span, ref offset);
            Eth1Data     eth1Data     = DecodeEth1Data(span, ref offset);
            Bytes32      graffiti     = new Bytes32(DecodeBytes32(span, ref offset));

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset1);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset2);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset3);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset4);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset5);

            // var part

            int proposerSlashingsLength = dynamicOffset2 - dynamicOffset1;
            int attesterSlashingsLength = dynamicOffset3 - dynamicOffset2;
            int attestationsLength      = dynamicOffset4 - dynamicOffset3;
            int depositsLength          = dynamicOffset5 - dynamicOffset4;
            int voluntaryExitsLength    = span.Length - dynamicOffset5;

            ProposerSlashing[] proposerSlashings = DecodeProposerSlashings(span.Slice(dynamicOffset1, proposerSlashingsLength));
            AttesterSlashing[] attesterSlashings = DecodeAttesterSlashings(span.Slice(dynamicOffset2, attesterSlashingsLength));
            Attestation[]      attestations      = DecodeAttestations(span.Slice(dynamicOffset3, attestationsLength));
            Deposit[]          deposits          = DecodeDeposits(span.Slice(dynamicOffset4, depositsLength));
            VoluntaryExit[]    voluntaryExits    = DecodeVoluntaryExits(span.Slice(dynamicOffset5, voluntaryExitsLength));

            BeaconBlockBody container = new BeaconBlockBody(randaoReveal,
                                                            eth1Data,
                                                            graffiti,
                                                            proposerSlashings,
                                                            attesterSlashings,
                                                            attestations,
                                                            deposits,
                                                            voluntaryExits);

            return(container);
        }
Esempio n. 27
0
        public static int BeaconBlockBodyLength(BeaconBlockBody container)
        {
            int result = BeaconBlockBodyDynamicOffset;

            result += Ssz.ProposerSlashingLength * container.ProposerSlashings.Count;
            result += Ssz.DepositLength() * container.Deposits.Count;
            result += Ssz.SignedVoluntaryExitLength * container.VoluntaryExits.Count;

            result += sizeof(uint) * container.AttesterSlashings.Count;
            for (int i = 0; i < container.AttesterSlashings.Count; i++)
            {
                result += Ssz.AttesterSlashingLength(container.AttesterSlashings[i]);
            }

            result += sizeof(uint) * container.Attestations.Count;
            for (int i = 0; i < container.Attestations.Count; i++)
            {
                result += Ssz.AttestationLength(container.Attestations[i]);
            }

            return(result);
        }
Esempio n. 28
0
        private static BeaconBlockBody DecodeBeaconBlockBody(ReadOnlySpan <byte> span, ref int offset)
        {
            // static part

            BlsSignature randaoReveal = DecodeBlsSignature(span, ref offset);
            Eth1Data     eth1Data     = DecodeEth1Data(span, ref offset);
            Bytes32      graffiti     = DecodeBytes32(span, ref offset);

            DecodeDynamicOffset(span, ref offset, out int dynamicOffset1);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset2);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset3);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset4);
            DecodeDynamicOffset(span, ref offset, out int dynamicOffset5);

            // var part

            int proposerSlashingsLength = dynamicOffset2 - dynamicOffset1;
            int attesterSlashingsLength = dynamicOffset3 - dynamicOffset2;
            int attestationsLength      = dynamicOffset4 - dynamicOffset3;
            int depositsLength          = dynamicOffset5 - dynamicOffset4;

            ProposerSlashing[] proposerSlashings = DecodeProposerSlashings(span.Slice(dynamicOffset1, proposerSlashingsLength));
            AttesterSlashing[] attesterSlashings = DecodeAttesterSlashings(span.Slice(dynamicOffset2, attesterSlashingsLength));
            Attestation[]      attestations      = DecodeAttestations(span.Slice(dynamicOffset3, attestationsLength));
            Deposit[]          deposits          = DecodeDeposits(span.Slice(dynamicOffset4, depositsLength));
            offset = dynamicOffset5;
            SignedVoluntaryExit[] signedVoluntaryExits = DecodeSignedVoluntaryExitVector(span, ref offset, span.Length);

            BeaconBlockBody container = new BeaconBlockBody(randaoReveal,
                                                            eth1Data,
                                                            graffiti,
                                                            proposerSlashings,
                                                            attesterSlashings,
                                                            attestations,
                                                            deposits,
                                                            signedVoluntaryExits);

            return(container);
        }
Esempio n. 29
0
        public void ProcessRandao(BeaconState state, BeaconBlockBody body)
        {
            _logger.LogInformation(Event.ProcessRandao, "Process block randao for block body {BeaconBlockBody}", body);
            var epoch = _beaconStateAccessor.GetCurrentEpoch(state);
            // Verify RANDAO reveal
            var beaconProposerIndex = _beaconStateAccessor.GetBeaconProposerIndex(state);
            var proposer            = state.Validators[(int)(ulong)beaconProposerIndex];
            var epochRoot           = epoch.HashTreeRoot();
            var domain            = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.Randao, Epoch.None);
            var validRandaoReveal = _cryptographyService.BlsVerify(proposer.PublicKey, epochRoot, body.RandaoReveal, domain);

            if (!validRandaoReveal)
            {
                throw new Exception($"Randao reveal {body.RandaoReveal} must match proposer public key {proposer.PublicKey}");
            }
            // Mix in RANDAO reveal
            var randaoMix   = _beaconStateAccessor.GetRandaoMix(state, epoch);
            var randaoHash  = _cryptographyService.Hash(body.RandaoReveal.AsSpan());
            var mix         = randaoMix.Xor(randaoHash);
            var randaoIndex = epoch % _stateListLengthOptions.CurrentValue.EpochsPerHistoricalVector;

            state.SetRandaoMix(randaoIndex, mix);
        }
Esempio n. 30
0
 public Root HashTreeRoot(BeaconBlockBody beaconBlockBody)
 {
     throw new NotImplementedException();
 }