@@ -133,11 +133,9 @@ class Context(Enum):
133
133
"storageCostsFiller.yml" ,
134
134
"variedContextFiller.yml" ,
135
135
"vitalikTransactionTestParisFiller.json" ,
136
-
137
136
# stExample
138
137
"add11_ymlFiller.yml" ,
139
138
"add11Filler.json" ,
140
-
141
139
# stExtCodeHash
142
140
"extcodehashEmpty_ParisFiller.yml" ,
143
141
"extCodeHashSelfInInitFiller.json" ,
@@ -164,7 +162,6 @@ class Context(Enum):
164
162
"extCodeHashCreatedAndDeletedAccountCallFiller.json" ,
165
163
"createEmptyThenExtcodehashFiller.json" ,
166
164
"contractCreationOOGdontLeaveEmptyContractViaTransactionFiller.json" ,
167
-
168
165
# Really only `ReturnTestFiller` and `ReturnTest2Filler` are compatible inside `stInitCodeTest`
169
166
"CallContractToCreateContractAndCallItOOGFiller.json" ,
170
167
"CallContractToCreateContractOOGBonusGasFiller.json" ,
@@ -179,8 +176,6 @@ class Context(Enum):
179
176
"OutOfGasContractCreationFiller.json" ,
180
177
"OutOfGasPrefundedContractCreationFiller.json" ,
181
178
"TransactionCreateStopInInitcodeFiller.json" ,
182
-
183
-
184
179
# stInitCodeTest
185
180
"ReturnTestFiller.json" ,
186
181
"ReturnTest2Filler.json" ,
@@ -189,7 +184,6 @@ class Context(Enum):
189
184
"CREATE_BoundsFiller.json" ,
190
185
"NonZeroValue_CALLCODEFiller.json" ,
191
186
"NonZeroValue_DELEGATECALLFiller.json" ,
192
-
193
187
"bufferFiller.yml" ,
194
188
"bufferSrcOffsetFiller.yml" ,
195
189
"callDataCopyOffsetFiller.json" ,
@@ -213,7 +207,6 @@ class Context(Enum):
213
207
"Create1000ShnghaiFiller.json" ,
214
208
"QuadraticComplexitySolidity_CallDataCopyFiller.json" ,
215
209
"testRandomTestFiller.json" ,
216
-
217
210
# uses coinbase address (0x41) as integer memory offsets. TODO: is this necessary for the test?
218
211
# we could end up changing this for compatibility instead.
219
212
"randomStatetest1Filler.json" ,
@@ -247,17 +240,14 @@ class Context(Enum):
247
240
"Call50000_sha256Filler.json" ,
248
241
"Create1000ByzantiumFiller.json" ,
249
242
"Create1000Filler.json" ,
250
-
251
243
# stRecursiveCreate
252
244
"RecursiveCreateContractsCreate4ContractsFiller.json" ,
253
245
"RecursiveCreateContractsFiller.json" ,
254
-
255
246
# stStackTests
256
247
"shallowStackFiller.json" ,
257
248
"stackOverflowFiller.json" ,
258
249
"stackOverflowDUPFiller.json" ,
259
250
"stackOverflowPUSHFiller.json" ,
260
-
261
251
"revertRetDataSizeFiller.yml" ,
262
252
"returndatacopy_0_0_following_successful_createFiller.json" ,
263
253
"RevertPrefoundFiller.json" ,
@@ -388,15 +378,12 @@ class Context(Enum):
388
378
"createNameRegistratorValueTooHighFiller.json" ,
389
379
"suicideCallerAddresTooBigLeftFiller.json" ,
390
380
"ABAcallsSuicide1Filler.json" ,
391
-
392
-
393
381
"/stCreate2/" ,
394
382
"/stCreateTest/" ,
395
383
"/stRecursiveCreate/" ,
396
384
"/stWalletTest/" ,
397
385
"/stZeroKnowledge/" ,
398
386
"/stZeroKnowledge2/" ,
399
-
400
387
# TODO: See if these can be turned on with fine tuning
401
388
"/stTimeConsuming/" ,
402
389
}
@@ -448,9 +435,7 @@ def is_incompatible_file(file_path: Path) -> bool:
448
435
"ccccccccccccccccccccccccccccccccccccccc1" ,
449
436
"ccccccccccccccccccccccccccccccccccccccc2" ,
450
437
},
451
- "callToSuicideThenExtcodehashFiller.json" : {
452
- "0000000000000000000000000000000000000025"
453
- },
438
+ "callToSuicideThenExtcodehashFiller.json" : {"0000000000000000000000000000000000000025" },
454
439
"doubleSelfdestructTouch_ParisFiller.yml" : {
455
440
"0000000000000000000000000000000000e49701" ,
456
441
"0000000000000000000000000000000000e49702" ,
@@ -466,7 +451,7 @@ def is_incompatible_file(file_path: Path) -> bool:
466
451
"coinbaseT2Filler.yml" ,
467
452
"doubleSelfdestructTouch_ParisFiller.yml" ,
468
453
"tooLongReturnDataCopyFiller.yml" ,
469
- "coinbaseWarmAccountCallGasFailFiller.yml"
454
+ "coinbaseWarmAccountCallGasFailFiller.yml" ,
470
455
}
471
456
472
457
# Fillers that should have precompile check disabled
@@ -576,9 +561,7 @@ def __init__(self, filename: str = ""):
576
561
self .coinbase_addr : Optional [str ] = None
577
562
self .target_addr : Optional [str ] = None
578
563
self .is_json = filename .lower ().endswith (".json" )
579
- self .skip_precompile_check = any (
580
- kw in filename for kw in DISABLE_PRECOMPILE_CHECK_FILLERS
581
- )
564
+ self .skip_precompile_check = any (kw in filename for kw in DISABLE_PRECOMPILE_CHECK_FILLERS )
582
565
self .no_tags_in_code = any (kw in filename for kw in NO_TAGS_IN_CODE )
583
566
self .validate_addr_entropy_in_code = any (
584
567
kw in filename for kw in VALIDATE_ADDR_ENTROPY_IN_CODE
@@ -628,9 +611,24 @@ def detect_context_change(self, line: str) -> Optional[Context]:
628
611
return None # Don't change context for empty storage
629
612
return Context .STORAGE
630
613
# Known fields that indicate we're back in NORMAL context
631
- elif any (kw in stripped for kw in {"balance:" , "nonce:" , "secretKey:" , "gasLimit:" ,
632
- "gasPrice:" , "value:" , "to:" , "from:" , "address:" ,
633
- "shouldnotexist:" , "indexes:" , "network:" , "result:" }):
614
+ elif any (
615
+ kw in stripped
616
+ for kw in {
617
+ "balance:" ,
618
+ "nonce:" ,
619
+ "secretKey:" ,
620
+ "gasLimit:" ,
621
+ "gasPrice:" ,
622
+ "value:" ,
623
+ "to:" ,
624
+ "from:" ,
625
+ "address:" ,
626
+ "shouldnotexist:" ,
627
+ "indexes:" ,
628
+ "network:" ,
629
+ "result:" ,
630
+ }
631
+ ):
634
632
return Context .NORMAL
635
633
return None
636
634
@@ -677,10 +675,7 @@ def collect_addresses(self, lines: List[str]) -> None:
677
675
for line_num , line in enumerate (lines , 1 ):
678
676
stripped = line .strip ()
679
677
stripped_no_spaces_or_quotes = (
680
- stripped .replace ('"' , "" )
681
- .replace ("'" , "" )
682
- .replace (" " , "" )
683
- .replace ("," , "" )
678
+ stripped .replace ('"' , "" ).replace ("'" , "" ).replace (" " , "" ).replace ("," , "" )
684
679
)
685
680
686
681
# Check for section changes
@@ -698,8 +693,9 @@ def collect_addresses(self, lines: List[str]) -> None:
698
693
if current_section in [Section .PRE , Section .RESULT ]:
699
694
# Check if this line is an address key (40 hex chars followed by colon)
700
695
# Also check for quoted addresses in JSON format
701
- if (re .match (r"^\s*(?:0x)?[a-fA-F0-9]{40}\s*:" , line , re .IGNORECASE ) or
702
- re .match (r'^\s*"(?:0x)?[a-fA-F0-9]{40}"\s*:' , line , re .IGNORECASE )):
696
+ if re .match (r"^\s*(?:0x)?[a-fA-F0-9]{40}\s*:" , line , re .IGNORECASE ) or re .match (
697
+ r'^\s*"(?:0x)?[a-fA-F0-9]{40}"\s*:' , line , re .IGNORECASE
698
+ ):
703
699
current_context = Context .NORMAL
704
700
705
701
# Don't reset context on closing braces - let field names determine context
@@ -777,9 +773,7 @@ def collect_addresses(self, lines: List[str]) -> None:
777
773
if (
778
774
code_content
779
775
and code_content not in ["" , "0x" , "0X" , "{}" , "[]" ]
780
- and (
781
- code_content in ["|" , ">" ] or len (code_content ) > 2
782
- )
776
+ and (code_content in ["|" , ">" ] or len (code_content ) > 2 )
783
777
):
784
778
self .addresses_with_code .add (current_address )
785
779
# Also check during CODE context for multi-line code
@@ -789,11 +783,7 @@ def collect_addresses(self, lines: List[str]) -> None:
789
783
kw in stripped_no_spaces_or_quotes
790
784
for kw in {"balance:" , "nonce:" , "storage:" }
791
785
):
792
- if (
793
- stripped
794
- and not stripped .startswith ("#" )
795
- and "{" not in stripped
796
- ):
786
+ if stripped and not stripped .startswith ("#" ) and "{" not in stripped :
797
787
# Any non-empty, non-comment, non-brace line in code section indicates there's code
798
788
self .addresses_with_code .add (current_address )
799
789
@@ -807,10 +797,7 @@ def collect_addresses(self, lines: List[str]) -> None:
807
797
if (
808
798
code_content
809
799
and code_content not in ["" , "0x" , "{}" , "[]" ]
810
- and (
811
- not code_content .startswith ("0x" )
812
- or len (code_content ) > 3
813
- )
800
+ and (not code_content .startswith ("0x" ) or len (code_content ) > 3 )
814
801
): # More than just "0x"
815
802
self .addresses_with_code .add (current_address )
816
803
@@ -958,9 +945,7 @@ def convert_line(self, line: str, section: Section, context: Context) -> str:
958
945
f"'{ KNOWN_SECRET_KEY } '" , f"'<eoa:sender:0x{ KNOWN_SECRET_KEY } >'"
959
946
)
960
947
elif KNOWN_SECRET_KEY in line :
961
- line = line .replace (
962
- KNOWN_SECRET_KEY , f'"<eoa:sender:0x{ KNOWN_SECRET_KEY } >"'
963
- )
948
+ line = line .replace (KNOWN_SECRET_KEY , f'"<eoa:sender:0x{ KNOWN_SECRET_KEY } >"' )
964
949
return line
965
950
966
951
# Sort addresses by length (longest first) to avoid partial replacements
@@ -984,20 +969,19 @@ def convert_line(self, line: str, section: Section, context: Context) -> str:
984
969
985
970
# Skip replacements in code/storage if no_tags_in_code is set
986
971
# EXCEPT for address keys which should always be replaced
987
- if self .no_tags_in_code and context in [Context .CODE , Context .STORAGE ] and not is_address_key :
972
+ if (
973
+ self .no_tags_in_code
974
+ and context in [Context .CODE , Context .STORAGE ]
975
+ and not is_address_key
976
+ ):
988
977
continue
989
978
990
979
# Use regex to find and replace addresses (case-insensitive)
991
980
# Pattern 1: Address followed by colon (as a key) - with or without 0x prefix
992
- pattern_key = re .compile (
993
- rf'(^|\s|"|\')(?:0x)?{ re .escape (addr )} (?=:)' , re .IGNORECASE
994
- )
981
+ pattern_key = re .compile (rf'(^|\s|"|\')(?:0x)?{ re .escape (addr )} (?=:)' , re .IGNORECASE )
995
982
if pattern_key .search (line ):
996
983
# Skip replacement if we're in storage context, depending on dont_replace_tags_in_storage_keys
997
- if (
998
- context != Context .STORAGE
999
- and not self .dont_replace_tags_in_storage_keys
1000
- ):
984
+ if context != Context .STORAGE and not self .dont_replace_tags_in_storage_keys :
1001
985
# Replace while preserving the prefix (whitespace, quote, etc)
1002
986
line = pattern_key .sub (r"\1" + tag , line )
1003
987
@@ -1022,38 +1006,26 @@ def protect_tag(match):
1022
1006
# In storage context, handle keys and values separately
1023
1007
if not self .dont_replace_tags_in_storage_keys :
1024
1008
# Replace addresses everywhere in storage, including keys
1025
- pattern_general = re .compile (
1026
- rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE
1027
- )
1028
- line_with_placeholders = pattern_general .sub (
1029
- tag , line_with_placeholders
1030
- )
1009
+ pattern_general = re .compile (rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE )
1010
+ line_with_placeholders = pattern_general .sub (tag , line_with_placeholders )
1031
1011
else :
1032
1012
# Default behavior: only replace in values, not keys
1033
1013
# Split by colon and only replace in values
1034
1014
parts = line_with_placeholders .split (":" )
1035
1015
for i in range (1 , len (parts )): # Skip first part (the key)
1036
1016
# Replace address in this part
1037
- pattern_general = re .compile (
1038
- rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE
1039
- )
1017
+ pattern_general = re .compile (rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE )
1040
1018
parts [i ] = pattern_general .sub (tag , parts [i ])
1041
1019
line_with_placeholders = ":" .join (parts )
1042
1020
else :
1043
1021
# Not in storage context - replace all occurrences
1044
- pattern_general = re .compile (
1045
- rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE
1046
- )
1047
- line_with_placeholders = pattern_general .sub (
1048
- tag , line_with_placeholders
1049
- )
1022
+ pattern_general = re .compile (rf"(?:0x)?{ re .escape (addr )} " , re .IGNORECASE )
1023
+ line_with_placeholders = pattern_general .sub (tag , line_with_placeholders )
1050
1024
1051
1025
# Restore protected tags
1052
1026
for i , protected_tag in enumerate (protected_tags ):
1053
1027
placeholder = f"__TAG_PLACEHOLDER_{ i } __"
1054
- line_with_placeholders = line_with_placeholders .replace (
1055
- placeholder , protected_tag
1056
- )
1028
+ line_with_placeholders = line_with_placeholders .replace (placeholder , protected_tag )
1057
1029
1058
1030
line = line_with_placeholders
1059
1031
@@ -1072,9 +1044,7 @@ def protect_tag(match):
1072
1044
# Only replace short names in code/storage values, not in address keys
1073
1045
if not is_address_key :
1074
1046
# Extract the hex part without 0x prefix from short_name
1075
- hex_part = (
1076
- short_name [2 :] if short_name .startswith ("0x" ) else short_name
1077
- )
1047
+ hex_part = short_name [2 :] if short_name .startswith ("0x" ) else short_name
1078
1048
1079
1049
# Create a pattern that matches the hex part with any number of leading/trailing zeros
1080
1050
# Pattern: optional 0x prefix, any number of zeros, the hex part, any number of zeros
@@ -1091,9 +1061,7 @@ def protect_tag(match):
1091
1061
for match in reversed (matches ):
1092
1062
# Only replace if it's a valid hex number (starts with 0x or is all hex)
1093
1063
match_text = match .group (0 )
1094
- if match_text .startswith ("0x" ) or match_text .startswith (
1095
- "0X"
1096
- ):
1064
+ if match_text .startswith ("0x" ) or match_text .startswith ("0X" ):
1097
1065
line = line [: match .start ()] + tag + line [match .end () :]
1098
1066
elif all (c in "0123456789abcdefABCDEF" for c in match_text ):
1099
1067
# Pure hex without 0x prefix - check context to ensure it's meant as an address
@@ -1102,16 +1070,10 @@ def protect_tag(match):
1102
1070
after = line [match .end () :].lstrip ()
1103
1071
if (
1104
1072
before .endswith (('"' , "'" , ":" , " " , "(" , "[" , "," ))
1105
- or after .startswith (
1106
- ('"' , "'" , " " , ")" , "]" , "," , "\n " )
1107
- )
1073
+ or after .startswith (('"' , "'" , " " , ")" , "]" , "," , "\n " ))
1108
1074
or not before
1109
1075
): # Start of line
1110
- line = (
1111
- line [: match .start ()]
1112
- + tag
1113
- + line [match .end () :]
1114
- )
1076
+ line = line [: match .start ()] + tag + line [match .end () :]
1115
1077
1116
1078
return line
1117
1079
@@ -1241,9 +1203,7 @@ def main():
1241
1203
converted_json += 1
1242
1204
print (f"Converted JSON: { file_path } " )
1243
1205
1244
- print (
1245
- f"\n Summary: Converted { converted_yaml } YAML files and { converted_json } JSON files"
1246
- )
1206
+ print (f"\n Summary: Converted { converted_yaml } YAML files and { converted_json } JSON files" )
1247
1207
1248
1208
1249
1209
if __name__ == "__main__" :
0 commit comments