public static (Deposit, Root) BuildDeposit(IServiceProvider testServiceProvider, BeaconState?state, IList <DepositData> depositDataList, BlsPublicKey publicKey, byte[] privateKey, Gwei amount, Bytes32 withdrawalCredentials, bool signed) { ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>(); DepositData depositData = BuildDepositData(testServiceProvider, publicKey, privateKey, amount, withdrawalCredentials, state, signed); int index = depositDataList.Count; depositDataList.Add(depositData); Root root = cryptographyService.HashTreeRoot(depositDataList); IEnumerable <Bytes32> allLeaves = depositDataList.Select(x => new Bytes32(cryptographyService.HashTreeRoot(x).AsSpan())); IList <IList <Bytes32> > tree = TestSecurity.CalculateMerkleTreeFromLeaves(allLeaves); IList <Bytes32> merkleProof = TestSecurity.GetMerkleProof(tree, index, 32); List <Bytes32> proof = new List <Bytes32>(merkleProof); Span <byte> indexBytes = new Span <byte>(new byte[32]); BitConverter.TryWriteBytes(indexBytes, (ulong)index + 1); if (!BitConverter.IsLittleEndian) { indexBytes.Slice(0, 8).Reverse(); } Bytes32 indexHash = new Bytes32(indexBytes); proof.Add(indexHash); Bytes32 leaf = new Bytes32(cryptographyService.HashTreeRoot(depositData).AsSpan()); bool checkValid = beaconChainUtility.IsValidMerkleBranch(leaf, proof, chainConstants.DepositContractTreeDepth + 1, (ulong)index, root); Deposit deposit = new Deposit(proof, depositData); return(deposit, root); }
public void IsValidGenesisStateFalseNotEnoughValidators() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true); MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount - 1; IList <DepositData> deposits = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: true); IDepositStore depositStore = testServiceProvider.GetService <IDepositStore>(); foreach (DepositData deposit in deposits) { depositStore.Place(deposit); } Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = miscellaneousParameters.MinimumGenesisTime; // Act BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp); // Assert IsValidGenesisState(testServiceProvider, state, false); }
private static Bytes32 DecodeBytes32(ReadOnlySpan <byte> span, ref int offset) { Bytes32 bytes32 = DecodeBytes32(span.Slice(offset, Bytes32Length)); offset += Bytes32Length; return(bytes32); }
/// <summary> /// Return from ``indices`` a random index sampled by effective balance. /// </summary> public ValidatorIndex ComputeProposerIndex(BeaconState state, IList <ValidatorIndex> indices, Bytes32 seed) { if (!indices.Any()) { throw new ArgumentException("Indices can not be empty", nameof(indices)); } ulong indexCount = (ulong)indices.Count; ValidatorIndex index = 0UL; Span <byte> randomInputBytes = stackalloc byte[40]; seed.AsSpan().CopyTo(randomInputBytes); while (true) { ValidatorIndex initialValidatorIndex = (ValidatorIndex)(index % indexCount); ValidatorIndex shuffledIndex = ComputeShuffledIndex(initialValidatorIndex, indexCount, seed); ValidatorIndex candidateIndex = indices[(int)shuffledIndex]; BinaryPrimitives.WriteUInt64LittleEndian(randomInputBytes.Slice(32), index / 32); Bytes32 randomHash = _cryptographyService.Hash(randomInputBytes); byte random = randomHash.AsSpan()[(int)(index % 32)]; Gwei effectiveBalance = state.Validators[(int)candidateIndex].EffectiveBalance; if ((effectiveBalance * byte.MaxValue) >= (_gweiValueOptions.CurrentValue.MaximumEffectiveBalance * random)) { return(candidateIndex); } index++; } }
public void Eth1VoteReset() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(); BeaconState state = TestState.PrepareTestState(testServiceProvider); TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; // skip ahead to the end of the voting period state.SetSlot((Slot)(timeParameters.SlotsPerEth1VotingPeriod - 1UL)); // add a vote for each skipped slot. for (Slot index = Slot.Zero; index < state.Slot + new Slot(1); index += new Slot(1)) { ulong eth1DepositIndex = state.Eth1DepositIndex; Root depositRoot = new Root(Enumerable.Repeat((byte)0xaa, 32).ToArray()); Bytes32 blockHash = new Bytes32(Enumerable.Repeat((byte)0xbb, 32).ToArray()); Eth1Data eth1Data = new Eth1Data(depositRoot, eth1DepositIndex, blockHash); state.AddEth1DataVote(eth1Data); } // Act RunProcessFinalUpdates(testServiceProvider, state); // Assert state.Eth1DataVotes.Count.ShouldBe(0); }
// FIXME: This is duplicate of beacon node, need to clean up public byte[] GeneratePrivateKey(ulong index) { Span <byte> input = new Span <byte>(new byte[32]); BigInteger bigIndex = new BigInteger(index); bool indexWriteSuccess = bigIndex.TryWriteBytes(input, out int indexBytesWritten, isUnsigned: true, isBigEndian: false); if (!indexWriteSuccess || indexBytesWritten == 0) { throw new Exception("Error getting input for quick start private key generation."); } Bytes32 bytes32 = Sha256.Compute(input); ReadOnlySpan <byte> hash = bytes32.AsSpan(); // Mocked start interop specifies to convert the hash as little endian (which is the default for BigInteger) BigInteger value = new BigInteger(hash.ToArray(), isUnsigned: true); BigInteger privateKey = value % s_curveOrder; // Note that the private key is an *unsigned*, *big endian* number // However, we want to pad the big endian on the left to get 32 bytes. // So, write as little endian (will pad to right), then reverse. // NOTE: Alternative, write to Span 64, and then slice based on bytesWritten to get the padding. Span <byte> privateKeySpan = new Span <byte>(new byte[32]); bool keyWriteSuccess = privateKey.TryWriteBytes(privateKeySpan, out int keyBytesWritten, isUnsigned: true, isBigEndian: false); if (!keyWriteSuccess) { throw new Exception("Error generating quick start private key."); } privateKeySpan.Reverse(); return(privateKeySpan.ToArray()); }
public void Get_hash_code_is_consistent() { var wrappedA = Bytes32.Wrap(TestItem.KeccakA.Bytes); Bytes32.Zero.GetHashCode().Should().NotBe(wrappedA.GetHashCode()); wrappedA.GetHashCode().Should().Be(wrappedA.GetHashCode()); }
/// <summary> /// Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. /// </summary> public static Deposit PrepareStateAndDeposit(IServiceProvider testServiceProvider, BeaconState state, ValidatorIndex validatorIndex, Gwei amount, Bytes32 withdrawalCredentials, bool signed) { ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); InitialValues initialValues = testServiceProvider.GetService <IOptions <InitialValues> >().Value; TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); byte[][] privateKeys = TestKeys.PrivateKeys(timeParameters).ToArray(); BlsPublicKey[] publicKeys = TestKeys.PublicKeys(timeParameters).ToArray(); byte[] privateKey = privateKeys[(int)(ulong)validatorIndex]; BlsPublicKey publicKey = publicKeys[(int)(ulong)validatorIndex]; if (withdrawalCredentials == Bytes32.Zero) { // insecurely use pubkey as withdrawal key if no credentials provided byte[] withdrawalCredentialBytes = TestSecurity.Hash(publicKey.AsSpan()); withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix; withdrawalCredentials = new Bytes32(withdrawalCredentialBytes); } List <DepositData> depositDataList = new List <DepositData>(); (Deposit deposit, Root depositRoot) = BuildDeposit(testServiceProvider, state, depositDataList, publicKey, privateKey, amount, withdrawalCredentials, signed); state.SetEth1DepositIndex(0); state.Eth1Data.SetDepositRoot(depositRoot); state.Eth1Data.SetDepositCount((ulong)depositDataList.Count); return(deposit); }
public void Some_is_not_null() { Bytes32 bytes32A = Bytes32.Wrap(TestItem.KeccakA.Bytes); bytes32A.Equals(null).Should().BeFalse(); bytes32A.Equals((object)null).Should().BeFalse(); }
public void Some_is_not_zero() { Bytes32 bytes32A = Bytes32.Wrap(TestItem.KeccakA.Bytes); bytes32A.Equals(Bytes32.Zero).Should().BeFalse(); bytes32A.Equals((object)Bytes32.Zero).Should().BeFalse(); }
public void Same_byte_arrays_give_equal_bytes32() { Bytes32 bytes32A = Bytes32.Wrap(TestItem.KeccakA.Bytes); Bytes32 bytes32B = Bytes32.Wrap(TestItem.KeccakA.Bytes); bytes32A.Should().Be(bytes32B); }
public void Equal_byte_arrays_give_equal_bytes32() { Bytes32 bytes32A = Bytes32.Wrap(TestItem.KeccakA.Bytes); Bytes32 bytes32B = Bytes32.Wrap((byte[])TestItem.KeccakA.Bytes.Clone()); bytes32A.Should().Be(bytes32B); }
public DepositData(BlsPublicKey publicKey, Bytes32 withdrawalCredentials, Gwei amount, BlsSignature signature) { PublicKey = publicKey; WithdrawalCredentials = withdrawalCredentials; Amount = amount; Signature = signature; // Signing over DepositMessage }
/// <summary> /// Return the randao mix at a recent ``epoch`` /// </summary> public Bytes32 GetRandaoMix(BeaconState state, Epoch epoch) { int index = (int)(epoch % _stateListLengthOptions.CurrentValue.EpochsPerHistoricalVector); Bytes32 mix = state.RandaoMixes[index]; return(mix); }
public void TestInitializeBeaconStateFromEth1() { bool useBls = true; // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useBls, useStore: true); ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount; (IList <Deposit> deposits, Root depositRoot) = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: useBls); Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = miscellaneousParameters.MinimumGenesisTime; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); // Act //# initialize beacon_state BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp, deposits); // Assert state.GenesisTime.ShouldBe(eth1Timestamp - eth1Timestamp % timeParameters.MinimumGenesisDelay + 2 * timeParameters.MinimumGenesisDelay); state.Validators.Count.ShouldBe(depositCount); state.Eth1Data.DepositRoot.ShouldBe(depositRoot); state.Eth1Data.DepositCount.ShouldBe((ulong)depositCount); state.Eth1Data.BlockHash.ShouldBe(eth1BlockHash); }
public void Same_before_and_after() { byte[] bytesA = new byte[32]; new Random(42).NextBytes(bytesA); Bytes32 a = new Bytes32(bytesA); Assert.AreEqual(bytesA.ToHexString(true), a.ToString()); }
public Bytes32 Hash(Bytes32 a, Bytes32 b) { Span <byte> input = new Span <byte>(new byte[Bytes32.Length * 2]); a.AsSpan().CopyTo(input); b.AsSpan().CopyTo(input.Slice(Bytes32.Length)); return(Hash(input)); }
public BeaconState InitializeBeaconStateFromEth1(Bytes32 eth1BlockHash, ulong eth1Timestamp, IList <Deposit> deposits) { if (_logger.IsInfo()) { Log.InitializeBeaconState(_logger, eth1BlockHash, eth1Timestamp, deposits.Count, null); } InitialValues initialValues = _initialValueOptions.CurrentValue; GweiValues gweiValues = _gweiValueOptions.CurrentValue; TimeParameters timeParameters = _timeParameterOptions.CurrentValue; StateListLengths stateListLengths = _stateListLengthOptions.CurrentValue; Fork fork = new Fork(initialValues.GenesisForkVersion, initialValues.GenesisForkVersion, _chainConstants.GenesisEpoch); ulong genesisTime = eth1Timestamp - (eth1Timestamp % timeParameters.MinimumGenesisDelay) + (2 * timeParameters.MinimumGenesisDelay); Eth1Data eth1Data = new Eth1Data(Root.Zero, (ulong)deposits.Count, eth1BlockHash); Root emptyBlockBodyRoot = _cryptographyService.HashTreeRoot(BeaconBlockBody.Zero); BeaconBlockHeader latestBlockHeader = new BeaconBlockHeader(emptyBlockBodyRoot); Bytes32[] randaoMixes = Enumerable.Repeat(eth1BlockHash, (int)stateListLengths.EpochsPerHistoricalVector) .ToArray(); BeaconState state = new BeaconState(genesisTime, fork, eth1Data, latestBlockHeader, randaoMixes, 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); Root 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(_chainConstants.GenesisEpoch); validator.SetActive(_chainConstants.GenesisEpoch); } } return(state); }
static ShaMerkleTree() { _zeroHashes[0] = new Bytes32(); for (int index = 1; index < 32; index++) { _zeroHashes[index] = new Bytes32(); HashStatic(_zeroHashes[index - 1].Unwrap(), _zeroHashes[index - 1].Unwrap(), _zeroHashes[index].Unwrap()); } }
public void Setup() { for (int i = 0; i < _testLeaves.Length; i++) { byte[] bytes = new byte[32]; bytes[i] = (byte)(i + 1); _testLeaves[i] = Bytes32.Wrap(bytes); } }
public void GlobalSetup() { for (int i = 0; i < _bytes.Length; i++) { byte[] bytes = new byte[32]; bytes[i % 32] = (byte)i; _bytes[i] = Bytes32.Wrap(bytes); } }
public void On_creation_sets_the_fields_properly() { byte[] bytes = new byte[32]; bytes[1] = 44; Bytes32 hash = Bytes32.Wrap(bytes); MerkleTreeNode merkleTreeNode = new MerkleTreeNode(hash, 5); merkleTreeNode.Hash.Should().Be(hash); merkleTreeNode.Index.Should().Be(5); }
public Bytes32 Hash(ReadOnlySpan <byte> bytes) { byte[] result = new byte[Bytes32.Length]; bool success = s_hashAlgorithm.TryComputeHash(bytes, result, out int bytesWritten); if (!success || bytesWritten != Bytes32.Length) { throw new Exception("Error generating hash value."); } return(Bytes32.Wrap(result)); }
public BeaconBlockBody() { RandaoReveal = BlsSignature.Empty; Eth1Data = new Eth1Data(0, Hash32.Zero); Graffiti = new Bytes32(); _proposerSlashings = new List <ProposerSlashing>(); _attesterSlashings = new List <AttesterSlashing>(); _attestations = new List <Attestation>(); _deposits = new List <Deposit>(); _voluntaryExits = new List <VoluntaryExit>(); }
public static Eth1Data DecodeEth1Data(ReadOnlySpan <byte> span) { if (span.Length != Ssz.Eth1DataLength) { ThrowSourceLength <Eth1Data>(span.Length, Ssz.Eth1DataLength); } Root depositRoot = DecodeRoot(span.Slice(0, Ssz.RootLength)); ulong depositCount = DecodeULong(span.Slice(Ssz.RootLength, sizeof(ulong))); Bytes32 blockHash = DecodeBytes32(span.Slice(Ssz.RootLength + sizeof(ulong), Ssz.Bytes32Length)); Eth1Data container = new Eth1Data(depositRoot, depositCount, blockHash); return(container); }
public void Can_merkleize_bytes32() { // arrange Bytes32 bytes32 = new Bytes32(Enumerable.Repeat((byte)0x34, 32).ToArray()); // act Merkle.Ize(out UInt256 root, bytes32); Span <byte> bytes = MemoryMarshal.Cast <UInt256, byte>(MemoryMarshal.CreateSpan(ref root, 1)); // assert byte[] expected = Enumerable.Repeat((byte)0x34, 32).ToArray(); bytes.ToArray().ShouldBe(expected); }
public bool Verify(Deposit deposit) { // TODO: need to be able to delete? // generally need to understand how the verification would work here and the current code at least // encapsulates deposits creation and verification Root depositDataRoot = _crypto.HashTreeRoot(deposit.Data); Bytes32 rootBytes = new Bytes32(depositDataRoot.AsSpan()); VerificationData.Insert(Bytes32.Wrap(deposit.Data.Root.Bytes)); bool isValid = VerificationData.VerifyProof(rootBytes, deposit.Proof, VerificationData.Count - 1); return(isValid); }
/// <summary> /// Return the beacon committee at ``slot`` for ``index``. /// </summary> public IReadOnlyList <ValidatorIndex> GetBeaconCommittee(BeaconState state, Slot slot, CommitteeIndex index) { Epoch epoch = _beaconChainUtility.ComputeEpochAtSlot(slot); ulong committeesPerSlot = GetCommitteeCountAtSlot(state, slot); IList <ValidatorIndex> indices = GetActiveValidatorIndices(state, epoch); Bytes32 seed = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconAttester); ulong committeeIndex = (slot % _timeParameterOptions.CurrentValue.SlotsPerEpoch) * committeesPerSlot + (ulong)index; ulong committeeCount = committeesPerSlot * _timeParameterOptions.CurrentValue.SlotsPerEpoch; IReadOnlyList <ValidatorIndex> committee = _beaconChainUtility.ComputeCommittee(indices, seed, committeeIndex, committeeCount); return(committee); }
private DepositData BuildAndSignDepositData(ulong validatorIndex, Gwei amount, SignatureDomains signatureDomains) { InitialValues initialValues = _initialValueOptions.CurrentValue; byte[] privateKey = GeneratePrivateKey(validatorIndex); // Public Key BLSParameters blsParameters = new BLSParameters { PrivateKey = privateKey }; using BLS bls = BLS.Create(blsParameters); byte[] publicKeyBytes = new byte[BlsPublicKey.Length]; bls.TryExportBlsPublicKey(publicKeyBytes, out int publicKeyBytesWritten); BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes); // Withdrawal Credentials Bytes32 withdrawalCredentials = _crypto.Hash(publicKey.AsSpan()); withdrawalCredentials.Unwrap()[0] = initialValues.BlsWithdrawalPrefix; // Build deposit data DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount, BlsSignature.Zero); // Sign deposit data Domain domain = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit); DepositMessage depositMessage = new DepositMessage( depositData.PublicKey, depositData.WithdrawalCredentials, depositData.Amount); Root depositMessageRoot = _crypto.HashTreeRoot(depositMessage); Root depositDataSigningRoot = _beaconChainUtility.ComputeSigningRoot(depositMessageRoot, domain); byte[] signatureBytes = new byte[96]; bls.TrySignData(depositDataSigningRoot.AsSpan(), signatureBytes, out int bytesWritten); BlsSignature depositDataSignature = new BlsSignature(signatureBytes); depositData.SetSignature(depositDataSignature); if (_logger.IsEnabled(LogLevel.Debug)) { LogDebug.QuickStartAddValidator(_logger, validatorIndex, publicKey.ToString().Substring(0, 12), null); } return(depositData); }
public static void Ize(out UInt256 root, Bytes32 value) { ReadOnlySpan <byte> readOnlyBytes = value.AsSpan(); unsafe { fixed(byte *buffer = &readOnlyBytes.GetPinnableReference()) { Span <byte> apiNeedsWriteableEvenThoughOnlyReading = new Span <byte>(buffer, readOnlyBytes.Length); UInt256.CreateFromLittleEndian(out root, apiNeedsWriteableEvenThoughOnlyReading); } } }