12
12
denoms ,
13
13
ValidationError ,
14
14
)
15
+ from eth_utils .toolz import assoc
15
16
16
17
from eth .constants import (
17
18
ZERO_HASH32 ,
@@ -779,28 +780,33 @@ def test_verify_vote_count(max_casper_votes, sample_slashable_vote_data_params,
779
780
assert verify_vote_count (votes , max_casper_votes )
780
781
781
782
782
- def _get_indices_and_signatures (num_validators , message , privkeys ):
783
+ def _get_indices_and_signatures (num_validators , message , privkeys , fork_data , slot ):
783
784
num_indices = 5
784
785
assert num_validators >= num_indices
785
786
indices = random .sample (range (num_validators ), num_indices )
786
787
privkeys = [privkeys [i ] for i in indices ]
787
- domain = SignatureDomain .DOMAIN_ATTESTATION
788
+ domain_type = SignatureDomain .DOMAIN_ATTESTATION
789
+ domain = get_domain (
790
+ fork_data = fork_data ,
791
+ slot = slot ,
792
+ domain_type = domain_type ,
793
+ )
788
794
signatures = tuple (
789
795
map (lambda key : bls .sign (message , key , domain ), privkeys )
790
796
)
791
797
return (indices , signatures )
792
798
793
799
794
- def _correct_slashable_vote_data_params (params , validators , messages , privkeys ):
800
+ def _correct_slashable_vote_data_params (num_validators , params , messages , privkeys , fork_data ):
795
801
valid_params = copy .deepcopy (params )
796
802
797
- num_validators = len (validators )
798
-
799
803
key = "custody_bit_0_indices"
800
804
(poc_0_indices , poc_0_signatures ) = _get_indices_and_signatures (
801
805
num_validators ,
802
806
messages [0 ],
803
807
privkeys ,
808
+ fork_data ,
809
+ params ["data" ].slot ,
804
810
)
805
811
valid_params [key ] = poc_0_indices
806
812
@@ -810,6 +816,8 @@ def _correct_slashable_vote_data_params(params, validators, messages, privkeys):
810
816
num_validators ,
811
817
messages [1 ],
812
818
privkeys ,
819
+ fork_data ,
820
+ params ["data" ].slot ,
813
821
)
814
822
valid_params [key ] = poc_1_indices
815
823
@@ -821,23 +829,32 @@ def _correct_slashable_vote_data_params(params, validators, messages, privkeys):
821
829
return valid_params
822
830
823
831
824
- def _corrupt_signature (params ):
825
- params = copy .deepcopy (params )
832
+ def _corrupt_signature (params , fork_data ):
826
833
message = bytes .fromhex ("deadbeefcafe" )
827
834
privkey = 42
828
- domain = SignatureDomain .DOMAIN_ATTESTATION
829
- params ["aggregate_signature" ] = bls .sign (message , privkey , domain )
830
- return params
835
+ domain_type = SignatureDomain .DOMAIN_ATTESTATION
836
+ domain = get_domain (
837
+ fork_data = fork_data ,
838
+ slot = params ["data" ].slot ,
839
+ domain_type = domain_type ,
840
+ )
841
+ corrupt_signature = bls .sign (message , privkey , domain )
842
+
843
+ return assoc (params , "aggregate_signature" , corrupt_signature )
831
844
832
845
833
846
def _corrupt_vote_count (params ):
834
- params = copy .deepcopy (params )
835
847
key = "custody_bit_0_indices"
836
848
for i in itertools .count ():
837
849
if i not in params [key ]:
838
- params [key ].append (i )
839
- break
840
- return params
850
+ new_vote_count = params [key ] + [i ]
851
+ return assoc (
852
+ params ,
853
+ key ,
854
+ new_vote_count ,
855
+ )
856
+ else :
857
+ raise Exception ("Unreachable code path" )
841
858
842
859
843
860
def _create_slashable_vote_data_messages (params ):
@@ -846,27 +863,47 @@ def _create_slashable_vote_data_messages(params):
846
863
return votes .messages
847
864
848
865
849
- def test_verify_slashable_vote_data_signature (privkeys ,
866
+ @pytest .mark .parametrize (
867
+ (
868
+ 'num_validators' ,
869
+ ),
870
+ [
871
+ (40 ,),
872
+ ]
873
+ )
874
+ def test_verify_slashable_vote_data_signature (num_validators ,
875
+ privkeys ,
850
876
sample_beacon_state_params ,
851
877
genesis_validators ,
852
- sample_slashable_vote_data_params ):
853
- sample_beacon_state_params ["validator_registry" ] = genesis_validators
854
- state = BeaconState (** sample_beacon_state_params )
878
+ sample_slashable_vote_data_params ,
879
+ sample_fork_data_params ):
880
+ beacon_state_params_with_genesis_validators = assoc (
881
+ sample_beacon_state_params ,
882
+ "validator_registry" ,
883
+ genesis_validators ,
884
+ )
885
+ beacon_state_params_with_fork_data = assoc (
886
+ beacon_state_params_with_genesis_validators ,
887
+ "fork_data" ,
888
+ ForkData (** sample_fork_data_params ),
889
+ )
890
+ state = BeaconState (** beacon_state_params_with_fork_data )
855
891
856
892
# NOTE: we can do this before "correcting" the params as they
857
893
# touch disjoint subsets of the provided params
858
894
messages = _create_slashable_vote_data_messages (sample_slashable_vote_data_params )
859
895
860
896
valid_params = _correct_slashable_vote_data_params (
897
+ num_validators ,
861
898
sample_slashable_vote_data_params ,
862
- genesis_validators ,
863
899
messages ,
864
900
privkeys ,
901
+ state .fork_data ,
865
902
)
866
903
valid_votes = SlashableVoteData (** valid_params )
867
904
assert verify_slashable_vote_data_signature (state , valid_votes )
868
905
869
- invalid_params = _corrupt_signature (valid_params )
906
+ invalid_params = _corrupt_signature (valid_params , state . fork_data )
870
907
invalid_votes = SlashableVoteData (** invalid_params )
871
908
assert not verify_slashable_vote_data_signature (state , invalid_votes )
872
909
@@ -882,37 +919,64 @@ def _run_verify_slashable_vote(params, state, max_casper_votes, should_succeed):
882
919
883
920
@pytest .mark .parametrize (
884
921
(
885
- 'param_mapper,'
886
- 'should_succeed'
922
+ 'num_validators' ,
887
923
),
888
924
[
889
- (lambda params : params , True ),
890
- (lambda params : _corrupt_vote_count (params ), False ),
891
- (lambda params : _corrupt_signature (params ), False ),
892
- (lambda params : _corrupt_vote_count (_corrupt_signature (params )), False ),
925
+ (40 ,),
926
+ ]
927
+ )
928
+ @pytest .mark .parametrize (
929
+ (
930
+ 'param_mapper' ,
931
+ 'should_succeed' ,
932
+ 'needs_fork_data' ,
933
+ ),
934
+ [
935
+ (lambda params : params , True , False ),
936
+ (_corrupt_vote_count , False , False ),
937
+ (_corrupt_signature , False , True ),
938
+ (lambda params , fork_data : _corrupt_vote_count (
939
+ _corrupt_signature (params , fork_data )
940
+ ), False , True ),
893
941
],
894
942
)
895
- def test_verify_slashable_vote_data (param_mapper ,
943
+ def test_verify_slashable_vote_data (num_validators ,
944
+ param_mapper ,
896
945
should_succeed ,
946
+ needs_fork_data ,
897
947
privkeys ,
898
948
sample_beacon_state_params ,
899
949
genesis_validators ,
900
950
sample_slashable_vote_data_params ,
951
+ sample_fork_data_params ,
901
952
max_casper_votes ):
902
- sample_beacon_state_params ["validator_registry" ] = genesis_validators
903
- state = BeaconState (** sample_beacon_state_params )
953
+ beacon_state_params_with_genesis_validators = assoc (
954
+ sample_beacon_state_params ,
955
+ "validator_registry" ,
956
+ genesis_validators ,
957
+ )
958
+ beacon_state_params_with_fork_data = assoc (
959
+ beacon_state_params_with_genesis_validators ,
960
+ "fork_data" ,
961
+ ForkData (** sample_fork_data_params ),
962
+ )
963
+ state = BeaconState (** beacon_state_params_with_fork_data )
904
964
905
965
# NOTE: we can do this before "correcting" the params as they
906
966
# touch disjoint subsets of the provided params
907
967
messages = _create_slashable_vote_data_messages (sample_slashable_vote_data_params )
908
968
909
969
params = _correct_slashable_vote_data_params (
970
+ num_validators ,
910
971
sample_slashable_vote_data_params ,
911
- genesis_validators ,
912
972
messages ,
913
973
privkeys ,
974
+ state .fork_data ,
914
975
)
915
- params = param_mapper (params )
976
+ if needs_fork_data :
977
+ params = param_mapper (params , state .fork_data )
978
+ else :
979
+ params = param_mapper (params )
916
980
_run_verify_slashable_vote (params , state , max_casper_votes , should_succeed )
917
981
918
982
0 commit comments