@@ -580,12 +580,12 @@ type CallArgs struct {
580
580
Data hexutil.Bytes `json:"data"`
581
581
}
582
582
583
- func (s * PublicBlockChainAPI ) doCall (ctx context.Context , args CallArgs , blockNr rpc.BlockNumber , vmCfg vm.Config ) ([]byte , * big.Int , error ) {
583
+ func (s * PublicBlockChainAPI ) doCall (ctx context.Context , args CallArgs , blockNr rpc.BlockNumber , vmCfg vm.Config ) ([]byte , * big.Int , bool , error ) {
584
584
defer func (start time.Time ) { log .Debug ("Executing EVM call finished" , "runtime" , time .Since (start )) }(time .Now ())
585
585
586
586
state , header , err := s .b .StateAndHeaderByNumber (ctx , blockNr )
587
587
if state == nil || err != nil {
588
- return nil , common .Big0 , err
588
+ return nil , common .Big0 , false , err
589
589
}
590
590
// Set sender address or use a default if none specified
591
591
addr := args .From
@@ -623,7 +623,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
623
623
// Get a new instance of the EVM.
624
624
evm , vmError , err := s .b .GetEVM (ctx , msg , state , header , vmCfg )
625
625
if err != nil {
626
- return nil , common .Big0 , err
626
+ return nil , common .Big0 , false , err
627
627
}
628
628
// Wait for the context to be done and cancel the evm. Even if the
629
629
// EVM has finished, cancelling may be done (repeatedly)
@@ -635,26 +635,28 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
635
635
// Setup the gas pool (also for unmetered requests)
636
636
// and apply the message.
637
637
gp := new (core.GasPool ).AddGas (math .MaxBig256 )
638
- // TODO utilize failed flag to help gas estimation
639
- res , gas , _ , err := core .ApplyMessage (evm , msg , gp )
638
+ res , gas , failed , err := core .ApplyMessage (evm , msg , gp )
640
639
if err := vmError (); err != nil {
641
- return nil , common .Big0 , err
640
+ return nil , common .Big0 , false , err
642
641
}
643
- return res , gas , err
642
+ return res , gas , failed , err
644
643
}
645
644
646
645
// Call executes the given transaction on the state for the given block number.
647
646
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
648
647
func (s * PublicBlockChainAPI ) Call (ctx context.Context , args CallArgs , blockNr rpc.BlockNumber ) (hexutil.Bytes , error ) {
649
- result , _ , err := s .doCall (ctx , args , blockNr , vm.Config {DisableGasMetering : true })
648
+ result , _ , _ , err := s .doCall (ctx , args , blockNr , vm.Config {DisableGasMetering : true })
650
649
return (hexutil .Bytes )(result ), err
651
650
}
652
651
653
652
// EstimateGas returns an estimate of the amount of gas needed to execute the given transaction.
654
653
func (s * PublicBlockChainAPI ) EstimateGas (ctx context.Context , args CallArgs ) (* hexutil.Big , error ) {
655
654
// Binary search the gas requirement, as it may be higher than the amount used
656
- var lo , hi uint64
657
- if (* big .Int )(& args .Gas ).Sign () != 0 {
655
+ var (
656
+ lo uint64 = params .TxGas - 1
657
+ hi uint64
658
+ )
659
+ if (* big .Int )(& args .Gas ).Uint64 () >= params .TxGas {
658
660
hi = (* big .Int )(& args .Gas ).Uint64 ()
659
661
} else {
660
662
// Retrieve the current pending block to act as the gas ceiling
@@ -669,10 +671,10 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*
669
671
mid := (hi + lo ) / 2
670
672
(* big .Int )(& args .Gas ).SetUint64 (mid )
671
673
672
- _ , gas , err := s .doCall (ctx , args , rpc .PendingBlockNumber , vm.Config {})
674
+ _ , _ , failed , err := s .doCall (ctx , args , rpc .PendingBlockNumber , vm.Config {})
673
675
674
- // If the transaction became invalid or used all the gas ( failed) , raise the gas limit
675
- if err != nil || gas . Cmp (( * big . Int )( & args . Gas )) == 0 {
676
+ // If the transaction became invalid or execution failed, raise the gas limit
677
+ if err != nil || failed {
676
678
lo = mid
677
679
continue
678
680
}
@@ -683,10 +685,11 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*
683
685
}
684
686
685
687
// ExecutionResult groups all structured logs emitted by the EVM
686
- // while replaying a transaction in debug mode as well as the amount of
687
- // gas used and the return value
688
+ // while replaying a transaction in debug mode as well as transaction
689
+ // execution status, the amount of gas used and the return value
688
690
type ExecutionResult struct {
689
691
Gas * big.Int `json:"gas"`
692
+ Failed bool `json:"failed"`
690
693
ReturnValue string `json:"returnValue"`
691
694
StructLogs []StructLogRes `json:"structLogs"`
692
695
}
0 commit comments