no custody bits fallback

This commit is contained in:
protolambda 2020-01-14 01:34:38 +01:00
parent e8654bff10
commit f6f8bd5350
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
4 changed files with 24 additions and 19 deletions

View File

@ -536,21 +536,26 @@ def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: Indexe
domain = get_domain(state, DOMAIN_BEACON_ATTESTER, attestation.data.target.epoch)
aggregation_bits = attestation.aggregation_bits
assert len(aggregation_bits) == len(indexed_attestation.committee)
for i, custody_bits in enumerate(attestation.custody_bits_blocks):
assert len(custody_bits) == len(indexed_attestation.committee)
for participant, abit, cbit in zip(indexed_attestation.committee, aggregation_bits, custody_bits):
if len(attestation.custody_bits_blocks) == 0:
# fall back on phase0 behavior if there is no shard data.
for participant, abit in zip(indexed_attestation.committee, aggregation_bits):
if abit:
all_pubkeys.append(state.validators[participant].pubkey)
# Note: only 2N distinct message hashes
all_signing_roots.append(compute_signing_root(
AttestationCustodyBitWrapper(hash_tree_root(attestation.data), i, cbit), domain))
else:
assert not cbit
# WARNING: this is BROKEN. If no custody_bits_blocks,
# a valid empty signature can pass validation, even though aggregate bits are set.
# Decide between: force at least 1 shard block (even if empty data),
# or fast-aggregate-verify with attestation data with empty shard data as message (alike to phase0)
return bls.AggregateVerify(zip(all_pubkeys, all_signing_roots), signature=attestation.signature)
signing_root = compute_signing_root(indexed_attestation.attestation.data, domain)
return bls.FastAggregateVerify(all_pubkeys, signing_root, signature=attestation.signature)
else:
for i, custody_bits in enumerate(attestation.custody_bits_blocks):
assert len(custody_bits) == len(indexed_attestation.committee)
for participant, abit, cbit in zip(indexed_attestation.committee, aggregation_bits, custody_bits):
if abit:
all_pubkeys.append(state.validators[participant].pubkey)
# Note: only 2N distinct message hashes
all_signing_roots.append(compute_signing_root(
AttestationCustodyBitWrapper(hash_tree_root(attestation.data), i, cbit), domain))
else:
assert not cbit
return bls.AggregateVerify(zip(all_pubkeys, all_signing_roots), signature=attestation.signature)
```

View File

@ -77,6 +77,7 @@ def sign_aggregate_attestation(spec, state, attestation_data, participants: List
privkey
)
)
# TODO: we should try signing custody bits if spec.version == 'phase1'
return bls.Aggregate(signatures)

View File

@ -1,6 +1,5 @@
from eth2spec.test.helpers.keys import privkeys
from eth2spec.utils import bls
from eth2spec.utils.hash_function import hash
from eth2spec.utils.ssz.ssz_typing import Bitlist, ByteVector, Bitvector
from eth2spec.utils.ssz.ssz_impl import chunkify, pack, hash_tree_root
from eth2spec.utils.merkle_minimal import get_merkle_tree, get_merkle_proof
@ -21,7 +20,7 @@ def get_valid_early_derived_secret_reveal(spec, state, epoch=None):
signing_root = spec.compute_signing_root(spec.Epoch(epoch), domain)
reveal = bls.Sign(privkeys[revealed_index], signing_root)
# Generate the mask (any random 32 bytes that don't reveal the masker's secret will do)
mask = hash(reveal)
mask = spec.hash(reveal)
# Generate masker's signature on the mask
signing_root = spec.compute_signing_root(mask, domain)
masker_signature = bls.Sign(privkeys[masker_index], signing_root)

View File

@ -2,7 +2,7 @@ from ..merkle_minimal import merkleize_chunks
from ..hash_function import hash
from .ssz_typing import (
SSZValue, SSZType, BasicValue, BasicType, Series, Elements, Bits, boolean, Container, List, ByteList,
Bitlist, Bitvector, uint,
Bitlist, Bitvector, uint, Bytes32
)
# SSZ Serialization
@ -140,7 +140,7 @@ def chunk_count(typ: SSZType) -> int:
raise Exception(f"Type not supported: {typ}")
def hash_tree_root(obj: SSZValue):
def hash_tree_root(obj: SSZValue) -> Bytes32:
if isinstance(obj, Series):
if is_bottom_layer_kind(obj.type()):
leaves = chunkify(pack(obj))
@ -152,6 +152,6 @@ def hash_tree_root(obj: SSZValue):
raise Exception(f"Type not supported: {type(obj)}")
if isinstance(obj, (List, ByteList, Bitlist)):
return mix_in_length(merkleize_chunks(leaves, limit=chunk_count(obj.type())), len(obj))
return Bytes32(mix_in_length(merkleize_chunks(leaves, limit=chunk_count(obj.type())), len(obj)))
else:
return merkleize_chunks(leaves)
return Bytes32(merkleize_chunks(leaves))