Skip to content

Commit 76b65eb

Browse files
Merge pull request #1681 from ChihChengLiang/add-beacon-chain-related-NewType
Add beacon chain related new type
2 parents 3b8fd86 + a19ca29 commit 76b65eb

28 files changed

+312
-162
lines changed

eth/_utils/bitfield.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,33 @@
1010
from itertools import (
1111
zip_longest,
1212
)
13+
from eth.beacon.typing import Bitfield
1314

1415

1516
@curry
16-
def has_voted(bitfield: bytes, index: int) -> bool:
17+
def has_voted(bitfield: Bitfield, index: int) -> bool:
1718
return bool(bitfield[index // 8] & (128 >> (index % 8)))
1819

1920

2021
@curry
21-
def set_voted(bitfield: bytes, index: int) -> bytes:
22+
def set_voted(bitfield: Bitfield, index: int) -> Bitfield:
2223
byte_index = index // 8
2324
bit_index = index % 8
2425
new_byte_value = bitfield[byte_index] | (128 >> bit_index)
25-
return bitfield[:byte_index] + bytes([new_byte_value]) + bitfield[byte_index + 1:]
26+
new_bitfield = bitfield[:byte_index] + bytes([new_byte_value]) + bitfield[byte_index + 1:]
27+
return Bitfield(new_bitfield)
2628

2729

2830
def get_bitfield_length(bit_count: int) -> int:
2931
"""Return the length of the bitfield for a given number of attesters in bytes."""
3032
return (bit_count + 7) // 8
3133

3234

33-
def get_empty_bitfield(bit_count: int) -> bytes:
34-
return b"\x00" * get_bitfield_length(bit_count)
35+
def get_empty_bitfield(bit_count: int) -> Bitfield:
36+
return Bitfield(b"\x00" * get_bitfield_length(bit_count))
3537

3638

37-
def get_vote_count(bitfield: bytes) -> int:
39+
def get_vote_count(bitfield: Bitfield) -> int:
3840
return len(
3941
tuple(
4042
index
@@ -44,10 +46,10 @@ def get_vote_count(bitfield: bytes) -> int:
4446
)
4547

4648

47-
def or_bitfields(bitfields: List[bytes]) -> bytes:
49+
def or_bitfields(bitfields: List[Bitfield]) -> Bitfield:
4850
byte_slices = zip_longest(*bitfields)
4951

5052
if len(set((len(b) for b in bitfields))) != 1:
5153
raise ValueError("The bitfield sizes are different")
5254

53-
return bytes(map(reduce(operator.or_), byte_slices))
55+
return Bitfield(bytes(map(reduce(operator.or_), byte_slices)))

eth/_utils/bls.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
)
3434
from eth.beacon._utils.hash import hash_eth2
3535

36+
from eth.beacon.typing import (
37+
BLSPubkey,
38+
BLSSignature,
39+
)
3640

3741
G2_cofactor = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109 # noqa: E501
3842
FQ2_order = q ** 2 - 1
@@ -134,7 +138,7 @@ def compress_G2(pt: Tuple[FQP, FQP, FQP]) -> Tuple[int, int]:
134138
)
135139

136140

137-
def decompress_G2(p: bytes) -> Tuple[FQP, FQP, FQP]:
141+
def decompress_G2(p: Tuple[int, int]) -> Tuple[FQP, FQP, FQP]:
138142
x1 = p[0] % 2**383
139143
y1_mod_2 = p[0] // 2**383
140144
x2 = p[1]
@@ -156,20 +160,21 @@ def decompress_G2(p: bytes) -> Tuple[FQP, FQP, FQP]:
156160
#
157161
def sign(message: bytes,
158162
privkey: int,
159-
domain: int) -> Tuple[int, int]:
160-
return compress_G2(
161-
multiply(
162-
hash_to_G2(message, domain),
163-
privkey
164-
)
165-
)
163+
domain: int) -> BLSSignature:
164+
return BLSSignature(
165+
compress_G2(
166+
multiply(
167+
hash_to_G2(message, domain),
168+
privkey
169+
)
170+
))
166171

167172

168-
def privtopub(k: int) -> int:
169-
return compress_G1(multiply(G1, k))
173+
def privtopub(k: int) -> BLSPubkey:
174+
return BLSPubkey(compress_G1(multiply(G1, k)))
170175

171176

172-
def verify(message: bytes, pubkey: int, signature: bytes, domain: int) -> bool:
177+
def verify(message: bytes, pubkey: BLSPubkey, signature: BLSSignature, domain: int) -> bool:
173178
try:
174179
final_exponentiation = final_exponentiate(
175180
pairing(
@@ -188,23 +193,23 @@ def verify(message: bytes, pubkey: int, signature: bytes, domain: int) -> bool:
188193
return False
189194

190195

191-
def aggregate_signatures(signatures: Sequence[bytes]) -> Tuple[int, int]:
196+
def aggregate_signatures(signatures: Sequence[BLSSignature]) -> BLSSignature:
192197
o = Z2
193198
for s in signatures:
194199
o = FQP_point_to_FQ2_point(add(o, decompress_G2(s)))
195-
return compress_G2(o)
200+
return BLSSignature(compress_G2(o))
196201

197202

198-
def aggregate_pubkeys(pubkeys: Sequence[int]) -> int:
203+
def aggregate_pubkeys(pubkeys: Sequence[BLSPubkey]) -> BLSPubkey:
199204
o = Z1
200205
for p in pubkeys:
201206
o = add(o, decompress_G1(p))
202-
return compress_G1(o)
207+
return BLSPubkey(compress_G1(o))
203208

204209

205-
def verify_multiple(pubkeys: Sequence[int],
210+
def verify_multiple(pubkeys: Sequence[BLSPubkey],
206211
messages: Sequence[bytes],
207-
signature: bytes,
212+
signature: BLSSignature,
208213
domain: int) -> bool:
209214
len_msgs = len(messages)
210215

eth/beacon/aggregation.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@
1111
set_voted,
1212
)
1313
from eth.beacon.enums import SignatureDomain
14+
from eth.beacon.typing import (
15+
BLSPubkey,
16+
BLSSignature,
17+
Bitfield,
18+
CommitteeIndex,
19+
)
1420

1521

1622
def verify_votes(
17-
message: bytes,
18-
votes: Iterable[Tuple[int, bytes, int]],
19-
domain: SignatureDomain) -> Tuple[Tuple[bytes, ...], Tuple[int, ...]]:
23+
message: bytes,
24+
votes: Iterable[Tuple[CommitteeIndex, BLSSignature, BLSPubkey]],
25+
domain: SignatureDomain
26+
) -> Tuple[Tuple[BLSSignature, ...], Tuple[CommitteeIndex, ...]]:
2027
"""
2128
Verify the given votes.
2229
@@ -37,10 +44,12 @@ def verify_votes(
3744
return sigs, committee_indices
3845

3946

40-
def aggregate_votes(bitfield: bytes,
41-
sigs: Iterable[bytes],
42-
voting_sigs: Iterable[bytes],
43-
voting_committee_indices: Iterable[int]) -> Tuple[bytes, Tuple[int, int]]:
47+
def aggregate_votes(
48+
bitfield: Bitfield,
49+
sigs: Iterable[BLSSignature],
50+
voting_sigs: Iterable[BLSSignature],
51+
voting_committee_indices: Iterable[CommitteeIndex]
52+
) -> Tuple[Bitfield, BLSSignature]:
4453
"""
4554
Aggregate the votes.
4655
"""

eth/beacon/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from eth.beacon.typing import BLSSignature
2+
13
#
24
# shuffle function
35
#
@@ -11,4 +13,4 @@
1113
# The highest possible result of the RNG.
1214
RAND_MAX = 2 ** (RAND_BYTES * 8) - 1
1315

14-
EMPTY_SIGNATURE = (0, 0)
16+
EMPTY_SIGNATURE = BLSSignature((0, 0))

eth/beacon/deposit_helpers.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,32 @@
2727
from eth.beacon.helpers import (
2828
get_domain,
2929
)
30+
from eth.beacon.typing import (
31+
SlotNumber,
32+
BLSPubkey,
33+
BLSSignature,
34+
ValidatorIndex,
35+
Gwei,
36+
)
3037

3138

3239
def get_min_empty_validator_index(validators: Sequence[ValidatorRecord],
33-
validator_balances: Sequence[int],
34-
current_slot: int,
35-
zero_balance_validator_ttl: int) -> int:
40+
validator_balances: Sequence[Gwei],
41+
current_slot: SlotNumber,
42+
zero_balance_validator_ttl: int) -> ValidatorIndex:
3643
for index, (validator, balance) in enumerate(zip(validators, validator_balances)):
3744
is_empty = (
3845
balance == 0 and
3946
validator.latest_status_change_slot + zero_balance_validator_ttl <= current_slot
4047
)
4148
if is_empty:
42-
return index
49+
return ValidatorIndex(index)
4350
raise MinEmptyValidatorIndexNotFound()
4451

4552

4653
def validate_proof_of_possession(state: BeaconState,
47-
pubkey: int,
48-
proof_of_possession: bytes,
54+
pubkey: BLSPubkey,
55+
proof_of_possession: BLSSignature,
4956
withdrawal_credentials: Hash32,
5057
randao_commitment: Hash32) -> None:
5158
deposit_input = DepositInput(
@@ -75,8 +82,8 @@ def validate_proof_of_possession(state: BeaconState,
7582

7683
def add_pending_validator(state: BeaconState,
7784
validator: ValidatorRecord,
78-
deposit: int,
79-
zero_balance_validator_ttl: int) -> Tuple[BeaconState, int]:
85+
deposit: Gwei,
86+
zero_balance_validator_ttl: int) -> Tuple[BeaconState, ValidatorIndex]:
8087
"""
8188
Add a validator to the existing minimum empty validator index or
8289
append to ``validator_registry``.
@@ -91,14 +98,13 @@ def add_pending_validator(state: BeaconState,
9198
)
9299
except MinEmptyValidatorIndexNotFound:
93100
index = None
94-
95101
# Append to the validator_registry
96102
validator_registry = state.validator_registry + (validator,)
97103
state = state.copy(
98104
validator_registry=validator_registry,
99105
validator_balances=state.validator_balances + (deposit, )
100106
)
101-
index = len(state.validator_registry) - 1
107+
index = ValidatorIndex(len(state.validator_registry) - 1)
102108
else:
103109
# Use the empty validator index
104110
state = state.update_validator(index, validator, deposit)
@@ -108,12 +114,12 @@ def add_pending_validator(state: BeaconState,
108114

109115
def process_deposit(*,
110116
state: BeaconState,
111-
pubkey: int,
112-
deposit: int,
113-
proof_of_possession: bytes,
117+
pubkey: BLSPubkey,
118+
deposit: Gwei,
119+
proof_of_possession: BLSSignature,
114120
withdrawal_credentials: Hash32,
115121
randao_commitment: Hash32,
116-
zero_balance_validator_ttl: int) -> Tuple[BeaconState, int]:
122+
zero_balance_validator_ttl: int) -> Tuple[BeaconState, ValidatorIndex]:
117123
"""
118124
Process a deposit from Ethereum 1.0.
119125
"""
@@ -142,7 +148,7 @@ def process_deposit(*,
142148
)
143149
else:
144150
# Top-up - increase balance by deposit
145-
index = validator_pubkeys.index(pubkey)
151+
index = ValidatorIndex(validator_pubkeys.index(pubkey))
146152
validator = state.validator_registry[index]
147153

148154
if validator.withdrawal_credentials != withdrawal_credentials:

0 commit comments

Comments
 (0)