@@ -135,6 +135,13 @@ def data_copy(compustate, size):
135
135
return True
136
136
137
137
138
+ def eat_gas (compustate , amount ):
139
+ if compustate .gas < amount :
140
+ return vm_exception ("OUT OF GAS" )
141
+ else :
142
+ compustate .gas -= amount
143
+
144
+
138
145
def vm_exception (error , ** kargs ):
139
146
log_vm_exit .trace ('EXCEPTION' , cause = error , ** kargs )
140
147
return 0 , 0 , []
@@ -331,6 +338,9 @@ def vm_execute(ext, msg, code):
331
338
elif op == 'ADDRESS' :
332
339
stk .append (utils .coerce_to_int (msg .to ))
333
340
elif op == 'BALANCE' :
341
+ if ext .post_anti_dos_hardfork ():
342
+ if not eat_gas (compustate , opcodes .BALANCE_SUPPLEMENTAL_GAS ):
343
+ return vm_exception ("OUT OF GAS" )
334
344
addr = utils .coerce_addr_to_hex (stk .pop () % 2 ** 160 )
335
345
stk .append (ext .get_balance (addr ))
336
346
elif op == 'ORIGIN' :
@@ -366,9 +376,15 @@ def vm_execute(ext, msg, code):
366
376
elif op == 'GASPRICE' :
367
377
stk .append (ext .tx_gasprice )
368
378
elif op == 'EXTCODESIZE' :
379
+ if ext .post_anti_dos_hardfork ():
380
+ if not eat_gas (compustate , opcodes .EXTCODELOAD_SUPPLEMENTAL_GAS ):
381
+ return vm_exception ("OUT OF GAS" )
369
382
addr = utils .coerce_addr_to_hex (stk .pop () % 2 ** 160 )
370
383
stk .append (len (ext .get_code (addr ) or b'' ))
371
384
elif op == 'EXTCODECOPY' :
385
+ if ext .post_anti_dos_hardfork ():
386
+ if not eat_gas (compustate , opcodes .EXTCODELOAD_SUPPLEMENTAL_GAS ):
387
+ return vm_exception ("OUT OF GAS" )
372
388
addr = utils .coerce_addr_to_hex (stk .pop () % 2 ** 160 )
373
389
start , s2 , size = stk .pop (), stk .pop (), stk .pop ()
374
390
extcode = ext .get_code (addr ) or b''
@@ -422,6 +438,9 @@ def vm_execute(ext, msg, code):
422
438
return vm_exception ('OOG EXTENDING MEMORY' )
423
439
mem [s0 ] = s1 % 256
424
440
elif op == 'SLOAD' :
441
+ if ext .post_anti_dos_hardfork ():
442
+ if not eat_gas (compustate , opcodes .SLOAD_SUPPLEMENTAL_GAS ):
443
+ return vm_exception ("OUT OF GAS" )
425
444
stk .append (ext .get_storage_data (msg .to , stk .pop ()))
426
445
elif op == 'SSTORE' :
427
446
s0 , s1 = stk .pop (), stk .pop ()
@@ -529,7 +548,10 @@ def vm_execute(ext, msg, code):
529
548
return vm_exception ('OOG EXTENDING MEMORY' )
530
549
if ext .get_balance (msg .to ) >= value and msg .depth < 1024 :
531
550
cd = CallData (mem , mstart , msz )
532
- create_msg = Message (msg .to , b'' , value , compustate .gas , cd , msg .depth + 1 )
551
+ ingas = compustate .gas
552
+ if ext .post_anti_dos_hardfork ():
553
+ ingas = ingas * opcodes .CALL_CHILD_LIMIT_NUM / CALL_CHILD_LIMIT_DENOM
554
+ create_msg = Message (msg .to , b'' , value , ingas , cd , msg .depth + 1 )
533
555
o , gas , addr = ext .create (create_msg )
534
556
if o :
535
557
stk .append (utils .coerce_to_int (addr ))
@@ -548,12 +570,21 @@ def vm_execute(ext, msg, code):
548
570
to = utils .encode_int (to )
549
571
to = ((b'\x00 ' * (32 - len (to ))) + to )[12 :]
550
572
extra_gas = (not ext .account_exists (to )) * opcodes .GCALLNEWACCOUNT + \
551
- (value > 0 ) * opcodes .GCALLVALUETRANSFER
573
+ (value > 0 ) * opcodes .GCALLVALUETRANSFER + \
574
+ ext .post_anti_dos_hardfork () * opcodes .CALL_SUPPLEMENTAL_GAS
575
+ submsg_gas = gas + opcodes .GSTIPEND * (value > 0 )
576
+ if ext .post_anti_dos_hardfork ():
577
+ if compustate .gas < extra_gas :
578
+ return vm_exception ('OUT OF GAS' , needed = extra_gas )
579
+ elif gas > (compustate .gas - extra_gas ) * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM :
580
+ gas = (compustate .gas - extra_gas ) * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM
581
+ else :
582
+ if compustate .gas < gas + extra_gas :
583
+ return vm_exception ('OUT OF GAS' , needed = gas + extra_gas )
552
584
submsg_gas = gas + opcodes .GSTIPEND * (value > 0 )
553
- if compustate .gas < gas + extra_gas :
554
- return vm_exception ('OUT OF GAS' , needed = gas + extra_gas )
555
585
if ext .get_balance (msg .to ) >= value and msg .depth < 1024 :
556
586
compustate .gas -= (gas + extra_gas )
587
+ assert compustate .gas >= 0
557
588
cd = CallData (mem , meminstart , meminsz )
558
589
call_msg = Message (msg .to , to , value , submsg_gas , cd ,
559
590
msg .depth + 1 , code_address = to )
@@ -579,12 +610,20 @@ def vm_execute(ext, msg, code):
579
610
if not mem_extend (mem , compustate , op , meminstart , meminsz ) or \
580
611
not mem_extend (mem , compustate , op , memoutstart , memoutsz ):
581
612
return vm_exception ('OOG EXTENDING MEMORY' )
582
- extra_gas = (value > 0 ) * opcodes .GCALLVALUETRANSFER
613
+ extra_gas = (value > 0 ) * opcodes .GCALLVALUETRANSFER + \
614
+ ext .post_anti_dos_hardfork () * opcodes .CALL_SUPPLEMENTAL_GAS
583
615
submsg_gas = gas + opcodes .GSTIPEND * (value > 0 )
584
- if compustate .gas < gas + extra_gas :
585
- return vm_exception ('OUT OF GAS' , needed = gas + extra_gas )
616
+ if ext .post_anti_dos_hardfork ():
617
+ if compustate .gas < extra_gas :
618
+ return vm_exception ('OUT OF GAS' , needed = extra_gas )
619
+ elif gas > (compustate .gas - extra_gas ) * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM :
620
+ gas = (compustate .gas - extra_gas ) * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM
621
+ else :
622
+ if compustate .gas < gas + extra_gas :
623
+ return vm_exception ('OUT OF GAS' , needed = gas + extra_gas )
586
624
if ext .get_balance (msg .to ) >= value and msg .depth < 1024 :
587
625
compustate .gas -= (gas + extra_gas )
626
+ assert compustate .gas >= 0
588
627
to = utils .encode_int (to )
589
628
to = ((b'\x00 ' * (32 - len (to ))) + to )[12 :]
590
629
cd = CallData (mem , meminstart , meminsz )
@@ -615,8 +654,12 @@ def vm_execute(ext, msg, code):
615
654
if not mem_extend (mem , compustate , op , datastart , datasz ) or \
616
655
not mem_extend (mem , compustate , op , codestart , codesz ):
617
656
return vm_exception ('OOG EXTENDING MEMORY' )
618
- if compustate .gas < gas :
619
- return vm_exception ('OUT OF GAS' , needed = gas )
657
+ if ext .post_anti_dos_hardfork ():
658
+ if gas > compustate .gas * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM :
659
+ gas = compustate .gas * opcodes .CALL_CHILD_LIMIT_NUM / opcodes .CALL_CHILD_LIMIT_DENOM
660
+ else :
661
+ if gas > compustate .gas :
662
+ return vm_exception ("OUT OF GAS" , needed = gas )
620
663
compustate .gas -= gas
621
664
code = '' .join ([chr (x ) for x in mem [codestart : codestart + codesz ]])
622
665
call_msg = Message ('\x00 ' * 20 , '\x00 ' * 20 , 0 , gas , CallData (mem , datastart , datasz ),
@@ -637,6 +680,11 @@ def vm_execute(ext, msg, code):
637
680
return vm_exception ('OOG EXTENDING MEMORY' )
638
681
return peaceful_exit ('RETURN' , compustate .gas , mem [s0 : s0 + s1 ])
639
682
elif op == 'SUICIDE' :
683
+ if ext .post_anti_dos_hardfork ():
684
+ if gas < opcodes .SUICIDE_SUPPLEMENTAL_GAS :
685
+ return vm_exception ("OUT OF GAS" )
686
+ else :
687
+ gas -= opcodes .SUICIDE_SUPPLEMENTAL_GAS
640
688
to = utils .encode_int (stk .pop ())
641
689
to = ((b'\x00 ' * (32 - len (to ))) + to )[12 :]
642
690
xfer = ext .get_balance (msg .to )
0 commit comments