private async Task RunOnAttestation(IServiceProvider testServiceProvider, BeaconState state, IStore store, Attestation attestation, bool expectValid) { MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; MaxOperationsPerBlock maxOperationsPerBlock = testServiceProvider.GetService <IOptions <MaxOperationsPerBlock> >().Value; IForkChoice forkChoice = testServiceProvider.GetService <IForkChoice>(); if (!expectValid) { Should.Throw <Exception>(async() => { await forkChoice.OnAttestationAsync(store, attestation); }); return; } BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); IndexedAttestation indexedAttestation = beaconStateAccessor.GetIndexedAttestation(state, attestation); await forkChoice.OnAttestationAsync(store, attestation); IEnumerable <ValidatorIndex> attestingIndices = beaconStateAccessor.GetAttestingIndices(state, attestation.Data, attestation.AggregationBits); ValidatorIndex firstAttestingIndex = attestingIndices.First(); LatestMessage latestMessage = (await store.GetLatestMessageAsync(firstAttestingIndex, true)) !; latestMessage.Epoch.ShouldBe(attestation.Data.Target.Epoch); latestMessage.Root.ShouldBe(attestation.Data.BeaconBlockRoot); }
public static AttesterSlashing GetValidAttesterSlashing(IServiceProvider testServiceProvider, BeaconState state, bool signed1, bool signed2) { TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); Attestation attestation1 = TestAttestation.GetValidAttestation(testServiceProvider, state, Slot.None, CommitteeIndex.None, signed1); Hash32 targetRoot2 = new Hash32(Enumerable.Repeat((byte)0x01, 32).ToArray()); Attestation attestation2 = new Attestation( attestation1.AggregationBits, new AttestationData(attestation1.Data.Slot, attestation1.Data.Index, attestation1.Data.BeaconBlockRoot, attestation1.Data.Source, new Checkpoint( attestation1.Data.Target.Epoch, targetRoot2 )), BlsSignature.Empty ); if (signed2) { TestAttestation.SignAttestation(testServiceProvider, state, attestation2); } IndexedAttestation indexedAttestation1 = beaconStateAccessor.GetIndexedAttestation(state, attestation1); IndexedAttestation indexedAttestation2 = beaconStateAccessor.GetIndexedAttestation(state, attestation2); AttesterSlashing attesterSlashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2); return(attesterSlashing); }
public AttesterSlashing( IndexedAttestation attestation1, IndexedAttestation attestation2) { Attestation1 = attestation1; Attestation2 = attestation2; }
public void Indexed_attestation_there_and_back() { AttestationData data = new AttestationData(); data.Slot = new Slot(1); data.CommitteeIndex = new CommitteeIndex(2); data.BeaconBlockRoot = Sha256.OfAnEmptyString; data.Source = new Checkpoint(new Epoch(1), Sha256.OfAnEmptyString); data.Target = new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString); IndexedAttestation container = new IndexedAttestation(); container.AttestingIndices = new ValidatorIndex[3]; container.Data = data; container.Signature = BlsSignature.TestSig1; Span <byte> encoded = new byte[IndexedAttestation.SszLength(container)]; Ssz.Encode(encoded, container); IndexedAttestation decoded = Ssz.DecodeIndexedAttestation(encoded); Assert.AreEqual(container, decoded); Merkle.Ize(out UInt256 root, container); }
public void Attester_slashing_there_and_back() { AttestationData data = new AttestationData( new Slot(1), new CommitteeIndex(2), Sha256.RootOfAnEmptyString, new Checkpoint(new Epoch(1), Sha256.RootOfAnEmptyString), new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString)); IndexedAttestation indexedAttestation1 = new IndexedAttestation( new ValidatorIndex[3], data, TestSig1); IndexedAttestation indexedAttestation2 = new IndexedAttestation( new ValidatorIndex[5], data, TestSig1); AttesterSlashing container = new AttesterSlashing(indexedAttestation1, indexedAttestation2); Span <byte> encoded = new byte[Ssz.AttesterSlashingLength(container)]; Ssz.Encode(encoded, container); AttesterSlashing?decoded = Ssz.DecodeAttesterSlashing(encoded); Assert.AreEqual(container, decoded); Merkle.Ize(out UInt256 root, container); }
private static IEnumerable <SszElement> GetValues(IndexedAttestation item, ulong maximumValidatorsPerCommittee) { yield return(item.AttestingIndices.ToSszBasicList(maximumValidatorsPerCommittee)); yield return(item.Data.ToSszContainer()); yield return(item.Signature.ToSszBasicVector()); }
public static void Ize(out UInt256 root, IndexedAttestation container) { Merkleizer merkleizer = new Merkleizer(2); merkleizer.Feed(container.AttestingIndices, Attestation.MaxValidatorsPerCommittee); merkleizer.Feed(container.Data); merkleizer.Feed(container.Signature); merkleizer.CalculateRoot(out root); }
private static IEnumerable <SszElement> GetValues(IndexedAttestation item, MiscellaneousParameters miscellaneousParameters) { yield return(item.CustodyBit0Indices.ToSszBasicList(miscellaneousParameters.MaximumValidatorsPerCommittee)); yield return(item.CustodyBit1Indices.ToSszBasicList(miscellaneousParameters.MaximumValidatorsPerCommittee)); yield return(item.Data.ToSszContainer()); yield return(item.Signature.ToSszBasicVector()); }
/// <summary> /// Return the indexed attestation corresponding to ``attestation``. /// </summary> public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation) { IEnumerable <ValidatorIndex> attestingIndices = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits); IOrderedEnumerable <ValidatorIndex> sortedAttestingIndices = attestingIndices.OrderBy(x => x); IndexedAttestation indexedAttestation = new IndexedAttestation(sortedAttestingIndices, attestation.Data, attestation.Signature); return(indexedAttestation); }
public static IndexedAttestation DecodeIndexedAttestation(Span <byte> span) { IndexedAttestation container = new IndexedAttestation(); int offset = 0; DecodeDynamicOffset(span, ref offset, out int dynamicOffset1); container.AttestingIndices = DecodeValidatorIndexes(span.Slice(dynamicOffset1)); container.Data = DecodeAttestationData(span, ref offset); container.Signature = DecodeBlsSignature(span, ref offset); return(container); }
private static void TestIndexedAttestationSsz(byte[] serialized, UInt256 expectedMerkleRoot, string testCaseDir) { IndexedAttestation container = Nethermind.Ssz.Ssz.DecodeIndexedAttestation(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 static IndexedAttestation DecodeIndexedAttestation(ReadOnlySpan <byte> span) { int offset = 0; DecodeDynamicOffset(span, ref offset, out int dynamicOffset1); ValidatorIndex[] attestingIndices = DecodeValidatorIndexes(span.Slice(dynamicOffset1)); AttestationData data = DecodeAttestationData(span, ref offset); BlsSignature signature = DecodeBlsSignature(span, ref offset); IndexedAttestation container = new IndexedAttestation(attestingIndices, data, signature); return(container); }
public static void Encode(Span <byte> span, IndexedAttestation container) { if (span.Length != IndexedAttestation.SszLength(container)) { ThrowTargetLength <IndexedAttestation>(span.Length, IndexedAttestation.SszLength(container)); } int offset = 0; int dynamicOffset = IndexedAttestation.SszDynamicOffset; Encode(span, container.AttestingIndices, ref offset, ref dynamicOffset); Encode(span, container.Data, ref offset); Encode(span, container.Signature, ref offset); }
public static AttesterSlashing DecodeAttesterSlashing(ReadOnlySpan <byte> span) { int offset1 = (int)DecodeUInt(span.Slice(0, VarOffsetSize)); int offset2 = (int)DecodeUInt(span.Slice(VarOffsetSize, VarOffsetSize)); int length1 = offset2 - offset1; int length2 = span.Length - offset2; IndexedAttestation attestation1 = DecodeIndexedAttestation(span.Slice(offset1, length1)); IndexedAttestation attestation2 = DecodeIndexedAttestation(span.Slice(offset2, length2)); AttesterSlashing attesterSlashing = new AttesterSlashing(attestation1, attestation2); return(attesterSlashing); }
/// <summary> /// Return the indexed attestation corresponding to ``attestation``. /// </summary> public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation) { var attestingIndices = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits); var custodyBit1Indices = GetAttestingIndices(state, attestation.Data, attestation.CustodyBits); var isSubset = custodyBit1Indices.All(x => attestingIndices.Contains(x)); if (!isSubset) { throw new Exception("Custody bit indices must be a subset of attesting indices"); } var custodyBit0Indices = attestingIndices.Except(custodyBit1Indices); var sortedCustodyBit0Indices = custodyBit0Indices.OrderBy(x => x); var sortedCustodyBit1Indices = custodyBit1Indices.OrderBy(x => x); var indexedAttestation = new IndexedAttestation(sortedCustodyBit0Indices, sortedCustodyBit1Indices, attestation.Data, attestation.Signature); return(indexedAttestation); }
/// <summary> /// Return the indexed attestation corresponding to ``attestation``. /// </summary> public IndexedAttestation GetIndexedAttestation(BeaconState state, Attestation attestation) { IEnumerable <ValidatorIndex> attestingIndices = GetAttestingIndices(state, attestation.Data, attestation.AggregationBits); IEnumerable <ValidatorIndex> custodyBit1Indices = GetAttestingIndices(state, attestation.Data, attestation.CustodyBits); bool isSubset = custodyBit1Indices.All(x => attestingIndices.Contains(x)); if (!isSubset) { throw new Exception("Custody bit indices must be a subset of attesting indices"); } IEnumerable <ValidatorIndex> custodyBit0Indices = attestingIndices.Except(custodyBit1Indices); IOrderedEnumerable <ValidatorIndex> sortedCustodyBit0Indices = custodyBit0Indices.OrderBy(x => x); IOrderedEnumerable <ValidatorIndex> sortedCustodyBit1Indices = custodyBit1Indices.OrderBy(x => x); IndexedAttestation indexedAttestation = new IndexedAttestation(sortedCustodyBit0Indices, sortedCustodyBit1Indices, attestation.Data, attestation.Signature); return(indexedAttestation); }
/// <summary> /// Check if ``indexed_attestation`` has valid indices and signature. /// </summary> public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain) { MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue; IReadOnlyList<ValidatorIndex> attestingIndices = indexedAttestation.AttestingIndices; // Verify max number of indices if ((ulong) attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee) { if (_logger.IsWarn()) Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, attestingIndices.Count, miscellaneousParameters.MaximumValidatorsPerCommittee, null); return false; } // Verify indices are sorted if (attestingIndices.Count() > 1) { for (int index = 0; index < attestingIndices.Count() - 1; index++) { if (!(attestingIndices[index] < attestingIndices[index + 1])) { if (_logger.IsWarn()) Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null); return false; } } } // Verify aggregate signature IEnumerable<BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int) (ulong) x].PublicKey); BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys); Hash32 messageHash = _cryptographyService.HashTreeRoot(indexedAttestation.Data); BlsSignature signature = indexedAttestation.Signature; bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, messageHash, signature, domain); if (!isValid) { if (_logger.IsWarn()) Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, null); return false; } return true; }
public void Indexed_attestation_there_and_back() { AttestationData data = new AttestationData( new Slot(1), new CommitteeIndex(2), Sha256.RootOfAnEmptyString, new Checkpoint(new Epoch(1), Sha256.RootOfAnEmptyString), new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString)); IndexedAttestation container = new IndexedAttestation( new ValidatorIndex[3], data, TestSig1); Span <byte> encoded = new byte[Ssz.IndexedAttestationLength(container)]; Ssz.Encode(encoded, container); IndexedAttestation decoded = Ssz.DecodeIndexedAttestation(encoded); decoded.ShouldBe(container); Merkle.Ize(out UInt256 root, container); }
public static void Encode(Span <byte> span, AttesterSlashing?container) { if (span.Length != AttesterSlashing.SszLength(container)) { ThrowTargetLength <AttesterSlashing>(span.Length, AttesterSlashing.SszLength(container)); } if (container == null) { return; } int dynamicOffset = 2 * VarOffsetSize; int length1 = IndexedAttestation.SszLength(container.Attestation1); Encode(span.Slice(0, VarOffsetSize), dynamicOffset); Encode(span.Slice(dynamicOffset, length1), container.Attestation1); dynamicOffset += IndexedAttestation.SszLength(container.Attestation1); int length2 = IndexedAttestation.SszLength(container.Attestation2); Encode(span.Slice(VarOffsetSize, VarOffsetSize), dynamicOffset); Encode(span.Slice(dynamicOffset, length2), container.Attestation2); }
/// <summary> /// Run ``on_attestation`` upon receiving a new ``attestation`` from either within a block or directly on the wire. /// An ``attestation`` that is asserted as invalid may be valid at a later time, /// consider scheduling it for later processing in such case. /// </summary> public async Task OnAttestationAsync(IStore store, Attestation attestation) { if (_logger.IsInfo()) { Log.OnAttestation(_logger, attestation, null); } TimeParameters timeParameters = _timeParameterOptions.CurrentValue; Checkpoint target = attestation.Data.Target; // Attestations must be from the current or previous epoch Slot currentSlot = GetCurrentSlot(store); Epoch currentEpoch = _beaconChainUtility.ComputeEpochAtSlot(currentSlot); // Use GENESIS_EPOCH for previous when genesis to avoid underflow Epoch previousEpoch = currentEpoch > _chainConstants.GenesisEpoch ? currentEpoch - new Epoch(1) : _chainConstants.GenesisEpoch; if (target.Epoch != currentEpoch && target.Epoch != previousEpoch) { throw new ArgumentOutOfRangeException("attestation.Target.Epoch", target.Epoch, $"Attestation target epoch must be either the current epoch {currentEpoch} or previous epoch {previousEpoch}."); } Epoch dataSlotEpoch = _beaconChainUtility.ComputeEpochAtSlot(attestation.Data.Slot); if (attestation.Data.Target.Epoch != dataSlotEpoch) { throw new ArgumentOutOfRangeException("attestation.Data.Target.Epoch", attestation.Data.Target.Epoch, $"Attestation data target epoch must match the attestation data slot {attestation.Data.Slot} (epoch {dataSlotEpoch})."); } // Attestations target be for a known block. If target block is unknown, delay consideration until the block is found BeaconBlock targetBlock = (await store.GetSignedBlockAsync(target.Root).ConfigureAwait(false)).Message; // Attestations cannot be from future epochs. If they are, delay consideration until the epoch arrives BeaconState targetStoredState = await store.GetBlockStateAsync(target.Root).ConfigureAwait(false); BeaconState baseState = BeaconState.Clone(targetStoredState); Slot targetEpochStartSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(target.Epoch); if (currentSlot < targetEpochStartSlot) { throw new Exception( $"Ättestation target epoch start slot {targetEpochStartSlot} should not be larger than the store current slot {currentSlot})."); } // Attestations must be for a known block. If block is unknown, delay consideration until the block is found BeaconBlock attestationBlock = (await store.GetSignedBlockAsync(attestation.Data.BeaconBlockRoot).ConfigureAwait(false)).Message; // Attestations must not be for blocks in the future. If not, the attestation should not be considered if (attestationBlock.Slot > attestation.Data.Slot) { throw new Exception( $"Attestation data root slot {attestationBlock.Slot} should not be larger than the attestation data slot {attestation.Data.Slot})."); } // Store target checkpoint state if not yet seen BeaconState?targetState = await store.GetCheckpointStateAsync(target, false).ConfigureAwait(false); if (targetState == null) { _beaconStateTransition.ProcessSlots(baseState, targetEpochStartSlot); await store.SetCheckpointStateAsync(target, baseState).ConfigureAwait(false); targetState = baseState; } // Attestations can only affect the fork choice of subsequent slots. // Delay consideration in the fork choice until their slot is in the past. Slot newCurrentSlot = GetCurrentSlot(store); if (newCurrentSlot < attestation.Data.Slot + 1) { throw new Exception( $"Attestation data slot {attestation.Data.Slot} should not be larger than the store current slot {newCurrentSlot})."); } // Get state at the `target` to validate attestation and calculate the committees IndexedAttestation indexedAttestation = _beaconStateAccessor.GetIndexedAttestation(targetState, attestation); Domain domain = _beaconStateAccessor.GetDomain(targetState, _signatureDomainOptions.CurrentValue.BeaconAttester, indexedAttestation.Data.Target.Epoch); bool isValid = _beaconChainUtility.IsValidIndexedAttestation(targetState, indexedAttestation, domain); if (!isValid) { throw new Exception($"Indexed attestation {indexedAttestation} is not valid."); } // Update latest messages IEnumerable <ValidatorIndex> attestingIndices = _beaconStateAccessor.GetAttestingIndices(targetState, attestation.Data, attestation.AggregationBits); foreach (ValidatorIndex index in attestingIndices) { LatestMessage?latestMessage = await store.GetLatestMessageAsync(index, false).ConfigureAwait(false); if (latestMessage == null || target.Epoch > latestMessage !.Epoch) { latestMessage = new LatestMessage(target.Epoch, attestation.Data.BeaconBlockRoot); await store.SetLatestMessageAsync(index, latestMessage).ConfigureAwait(false); } } }
public SszBeaconBlockBodyBenchmark() { AttestationData data = new AttestationData( new Slot(1), new CommitteeIndex(4), Sha256.RootOfAnEmptyString, new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString), new Checkpoint(new Epoch(3), Sha256.RootOfAnEmptyString)); Attestation attestation = new Attestation( new BitArray(new byte[5]), data, TestSig1 ); DepositData depositData = new DepositData( TestKey1, Sha256.Bytes32OfAnEmptyString, new Gwei(7), TestSig1); Deposit deposit = new Deposit( new Bytes32[Ssz.DepositContractTreeDepth + 1], depositData); IndexedAttestation indexedAttestation1 = new IndexedAttestation( new ValidatorIndex[8], data, TestSig1); IndexedAttestation indexedAttestation2 = new IndexedAttestation( new ValidatorIndex[8], data, TestSig1); AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2); Eth1Data eth1Data = new Eth1Data( Sha256.RootOfAnEmptyString, 9, Sha256.Bytes32OfAnEmptyString); Attestation[] attestations = new Attestation[3]; attestations[1] = attestation; Deposit[] deposits = new Deposit[3]; deposits[2] = deposit; Bytes32 graffiti = new Bytes32(new byte[32]); AttesterSlashing[] attesterSlashings = new AttesterSlashing[3]; attesterSlashings[0] = slashing; ProposerSlashing[] proposerSlashings = new ProposerSlashing[10]; BlsSignature randaoReveal = TestSig1; SignedVoluntaryExit[] signedVoluntaryExits = new SignedVoluntaryExit[11]; _body = new BeaconBlockBody(randaoReveal, eth1Data, graffiti, proposerSlashings, attesterSlashings, attestations, deposits, signedVoluntaryExits); _encoded = new byte[Ssz.BeaconBlockBodyLength(_body)]; }
public void Beacon_block_body_more_detailed() { BeaconBlockBody body = new BeaconBlockBody(); AttestationData data = new AttestationData(); data.Slot = new Slot(1); data.Source = new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString); data.Target = new Checkpoint(new Epoch(3), Sha256.OfAnEmptyString); data.CommitteeIndex = new CommitteeIndex(4); data.BeaconBlockRoot = Sha256.OfAnEmptyString; Attestation attestation = new Attestation(); attestation.Data = data; attestation.Signature = BlsSignature.TestSig1; attestation.AggregationBits = new byte[5]; DepositData depositData = new DepositData(); depositData.Amount = new Gwei(7); depositData.Signature = BlsSignature.TestSig1; depositData.PublicKey = BlsPublicKey.TestKey1; depositData.WithdrawalCredentials = Sha256.OfAnEmptyString; Deposit deposit = new Deposit(); deposit.Data = depositData; deposit.Proof = new Hash32[Deposit.ContractTreeDepth + 1]; IndexedAttestation indexedAttestation1 = new IndexedAttestation(); indexedAttestation1.Data = data; indexedAttestation1.Signature = BlsSignature.TestSig1; indexedAttestation1.AttestingIndices = new ValidatorIndex[8]; IndexedAttestation indexedAttestation2 = new IndexedAttestation(); indexedAttestation2.Data = data; indexedAttestation2.Signature = BlsSignature.TestSig1; indexedAttestation2.AttestingIndices = new ValidatorIndex[8]; AttesterSlashing slashing = new AttesterSlashing(); slashing.Attestation1 = indexedAttestation1; slashing.Attestation2 = indexedAttestation2; Eth1Data eth1Data = new Eth1Data(); eth1Data.BlockHash = Sha256.OfAnEmptyString; eth1Data.DepositCount = 9; eth1Data.DepositRoot = Sha256.OfAnEmptyString; body.Attestations = new Attestation[3]; body.Attestations[1] = attestation; body.Deposits = new Deposit[3]; body.Deposits[2] = deposit; body.Graffiti = new byte[32]; body.AttesterSlashings = new AttesterSlashing[3]; body.AttesterSlashings[0] = slashing; body.Eth1Data = eth1Data; body.ProposerSlashings = new ProposerSlashing[10]; body.RandaoReversal = BlsSignature.TestSig1; body.VoluntaryExits = new VoluntaryExit[11]; byte[] encoded = new byte[BeaconBlockBody.SszLength(body)]; Ssz.Encode(encoded, body); }
public void Beacon_block_body_more_detailed() { AttestationData data = new AttestationData( new Slot(1), new CommitteeIndex(4), Sha256.RootOfAnEmptyString, new Checkpoint(new Epoch(2), Sha256.RootOfAnEmptyString), new Checkpoint(new Epoch(3), Sha256.RootOfAnEmptyString)); Attestation attestation = new Attestation( new BitArray(new byte[5]), data, TestSig1); DepositData depositData = new DepositData( TestKey1, Sha256.Bytes32OfAnEmptyString, new Gwei(7), TestSig1); Deposit deposit = new Deposit(Enumerable.Repeat(Bytes32.Zero, Ssz.DepositContractTreeDepth + 1), depositData); IndexedAttestation indexedAttestation1 = new IndexedAttestation( new ValidatorIndex[8], data, TestSig1); IndexedAttestation indexedAttestation2 = new IndexedAttestation( new ValidatorIndex[8], data, TestSig1); AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2); Eth1Data eth1Data = new Eth1Data( Sha256.RootOfAnEmptyString, 9, Sha256.Bytes32OfAnEmptyString); Attestation[] attestations = Enumerable.Repeat(Attestation.Zero, 3).ToArray(); attestations[1] = attestation; Deposit zeroDeposit = new Deposit(Enumerable.Repeat(Bytes32.Zero, Ssz.DepositContractTreeDepth + 1), DepositData.Zero); Deposit[] deposits = Enumerable.Repeat(zeroDeposit, 3).ToArray(); deposits[2] = deposit; Bytes32 graffiti = new Bytes32(new byte[32]); AttesterSlashing[] attesterSlashings = Enumerable.Repeat(AttesterSlashing.Zero, 3).ToArray(); attesterSlashings[0] = slashing; ProposerSlashing[] proposerSlashings = Enumerable.Repeat(ProposerSlashing.Zero, 10).ToArray(); SignedVoluntaryExit[] signedVoluntaryExits = Enumerable.Repeat(SignedVoluntaryExit.Zero, 11).ToArray(); BeaconBlockBody body = new BeaconBlockBody( TestSig1, eth1Data, graffiti, proposerSlashings, attesterSlashings, attestations, deposits, signedVoluntaryExits ); byte[] encoded = new byte[Ssz.BeaconBlockBodyLength(body)]; Ssz.Encode(encoded, body); }
public void Beacon_block_body_more_detailed() { AttestationData data = new AttestationData( new Slot(1), new CommitteeIndex(4), Sha256.OfAnEmptyString, new Checkpoint(new Epoch(2), Sha256.OfAnEmptyString), new Checkpoint(new Epoch(3), Sha256.OfAnEmptyString)); Attestation attestation = new Attestation( new BitArray(new byte[5]), data, SszTest.TestSig1); DepositData depositData = new DepositData( SszTest.TestKey1, Sha256.OfAnEmptyString, new Gwei(7), SszTest.TestSig1); Deposit deposit = new Deposit(new Hash32[Ssz.DepositContractTreeDepth + 1], depositData); IndexedAttestation indexedAttestation1 = new IndexedAttestation( new ValidatorIndex[8], data, SszTest.TestSig1); IndexedAttestation indexedAttestation2 = new IndexedAttestation( new ValidatorIndex[8], data, SszTest.TestSig1); AttesterSlashing slashing = new AttesterSlashing(indexedAttestation1, indexedAttestation2); Eth1Data eth1Data = new Eth1Data( Sha256.OfAnEmptyString, 9, Sha256.OfAnEmptyString); Attestation[] attestations = new Attestation[3]; attestations[1] = attestation; Deposit[] deposits = new Deposit[3]; deposits[2] = deposit; Bytes32 graffiti = new Bytes32(new byte[32]); AttesterSlashing[] attesterSlashings = new AttesterSlashing[3]; attesterSlashings[0] = slashing; ProposerSlashing[] proposerSlashings = new ProposerSlashing[10]; VoluntaryExit[] voluntaryExits = new VoluntaryExit[11]; BeaconBlockBody body = new BeaconBlockBody( SszTest.TestSig1, eth1Data, graffiti, proposerSlashings, attesterSlashings, attestations, deposits, voluntaryExits ); byte[] encoded = new byte[Ssz.BeaconBlockBodyLength(body)]; Ssz.Encode(encoded, body); }
public static SszContainer ToSszContainer(this IndexedAttestation item, ulong maximumValidatorsPerCommittee) { return(new SszContainer(GetValues(item, maximumValidatorsPerCommittee))); }
/// <summary> /// Check if ``indexed_attestation`` has valid indices and signature. /// </summary> public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain) { MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue; IList <ValidatorIndex> bit0Indices = indexedAttestation.CustodyBit0Indices; IList <ValidatorIndex> bit1Indices = indexedAttestation.CustodyBit1Indices; // Verify no index has custody bit equal to 1 [to be removed in phase 1] if (bit1Indices.Count != 0) // [to be removed in phase 1] { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {BitIndicesCount} bit 1 indices.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot, bit1Indices.Count()); } return(false); //[to be removed in phase 1] } // Verify max number of indices int totalIndices = bit0Indices.Count + bit1Indices.Count; if ((ulong)totalIndices > miscellaneousParameters.MaximumValidatorsPerCommittee) { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has total indices {TotalIndices}, more than the maximum validators per committe {MaximumValidatorsPerCommittee}.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot, totalIndices, miscellaneousParameters.MaximumValidatorsPerCommittee); } return(false); } // Verify index sets are disjoint IEnumerable <ValidatorIndex> intersect = bit0Indices.Intersect(bit1Indices); if (intersect.Count() != 0) { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because it has {IntersectingValidatorCount} validator indexes in common between custody bit 0 and custody bit 1.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot, intersect.Count()); } return(false); } // Verify indices are sorted if (bit0Indices.Count() > 1) { for (int index = 0; index < bit0Indices.Count() - 1; index++) { if (!(bit0Indices[index] < bit0Indices[index + 1])) { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 0 index {IndexNumber} is not sorted.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index); } return(false); } } } if (bit1Indices.Count() > 1) { for (int index = 0; index < bit1Indices.Count() - 1; index++) { if (!(bit1Indices[index] < bit1Indices[index + 1])) { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because custody bit 1 index {IndexNumber} is not sorted.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot, index); } return(false); } } } // Verify aggregate signature IEnumerable <BlsPublicKey> bit0PublicKeys = bit0Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey); BlsPublicKey bit0AggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(bit0PublicKeys); IEnumerable <BlsPublicKey> bit1PublicKeys = bit1Indices.Select(x => state.Validators[(int)(ulong)x].PublicKey); BlsPublicKey bit1AggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(bit1PublicKeys); BlsPublicKey[] publicKeys = new[] { bit0AggregatePublicKey, bit1AggregatePublicKey }; AttestationDataAndCustodyBit attestationDataAndCustodyBit0 = new AttestationDataAndCustodyBit(indexedAttestation.Data, false); Hash32 messageHashBit0 = attestationDataAndCustodyBit0.HashTreeRoot(); AttestationDataAndCustodyBit attestationDataAndCustodyBit1 = new AttestationDataAndCustodyBit(indexedAttestation.Data, true); Hash32 messageHashBit1 = attestationDataAndCustodyBit1.HashTreeRoot(); Hash32[] messageHashes = new[] { messageHashBit0, messageHashBit1 }; BlsSignature signature = indexedAttestation.Signature; bool isValid = _cryptographyService.BlsVerifyMultiple(publicKeys, messageHashes, signature, domain); if (!isValid) { if (_logger.IsWarn()) { _logger.LogWarning(Event.InvalidIndexedAttestation, "Invalid indexed attestion from committee {CommitteeIndex} for slot {Slot}, because the aggregate signature does not match.", indexedAttestation.Data.Index, indexedAttestation.Data.Slot); } return(false); } return(true); }
/// <summary> /// Check if ``indexed_attestation`` has valid indices and signature. /// </summary> public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain) { MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue; IReadOnlyList <ValidatorIndex> attestingIndices = indexedAttestation.AttestingIndices; // Verify max number of indices if ((ulong)attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, attestingIndices.Count, miscellaneousParameters.MaximumValidatorsPerCommittee, null); } return(false); } // Verify indices are sorted and unique if (attestingIndices.Count() > 1) { for (int index = 0; index < attestingIndices.Count() - 1; index++) { if (!(attestingIndices[index] < attestingIndices[index + 1])) { if (attestingIndices[index] == attestingIndices[index + 1]) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationNotUnique(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null); } } else { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null); } } return(false); } } } // TODO: BLS FastAggregateVerify (see spec) // Verify aggregate signature IList <BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int)(ulong)x].PublicKey) .ToList(); Root attestationDataRoot = _cryptographyService.HashTreeRoot(indexedAttestation.Data); Root signingRoot = ComputeSigningRoot(attestationDataRoot, domain); BlsSignature signature = indexedAttestation.Signature; //BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys); //bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, signingRoot, signature); bool isValid = _cryptographyService.BlsFastAggregateVerify(publicKeys, signingRoot, signature); if (!isValid) { if (_logger.IsWarn()) { Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, null); } return(false); } return(true); }
public static SszContainer ToSszContainer(this IndexedAttestation item, MiscellaneousParameters miscellaneousParameters) { return(new SszContainer(GetValues(item, miscellaneousParameters))); }