@@ -50,42 +50,43 @@ const (
5050
5151// run runs the [PrecompiledContract], differentiating between stateful and
5252// regular types.
53- func (args * evmCallArgs ) run (p PrecompiledContract , input []byte ) (ret []byte , err error ) {
53+ func (args * evmCallArgs ) run (p PrecompiledContract , input []byte , suppliedGas uint64 ) (ret []byte , remainingGas uint64 , err error ) {
5454 if p , ok := p .(statefulPrecompile ); ok {
55- return p . run (args , input )
55+ return p (args , input , suppliedGas )
5656 }
57- return p .Run (input )
57+ // Gas consumption for regular precompiles was already handled by the native
58+ // RunPrecompiledContract(), which called this method.
59+ ret , err = p .Run (input )
60+ return ret , suppliedGas , err
5861}
5962
60- // PrecompiledStatefulRun is the stateful equivalent of the Run() method of a
63+ // PrecompiledStatefulContract is the stateful equivalent of a
6164// [PrecompiledContract].
62- type PrecompiledStatefulRun func (env PrecompileEnvironment , input []byte ) ([]byte , error )
65+ type PrecompiledStatefulContract func (env PrecompileEnvironment , input []byte , suppliedGas uint64 ) (ret []byte , remainingGas uint64 , err error )
6366
6467// NewStatefulPrecompile constructs a new PrecompiledContract that can be used
6568// via an [EVM] instance but MUST NOT be called directly; a direct call to Run()
6669// reserves the right to panic. See other requirements defined in the comments
6770// on [PrecompiledContract].
68- func NewStatefulPrecompile (run PrecompiledStatefulRun , requiredGas func ([]byte ) uint64 ) PrecompiledContract {
69- return statefulPrecompile {
70- gas : requiredGas ,
71- run : run ,
72- }
71+ func NewStatefulPrecompile (run PrecompiledStatefulContract ) PrecompiledContract {
72+ return statefulPrecompile (run )
7373}
7474
75- type statefulPrecompile struct {
76- gas func ([]byte ) uint64
77- run PrecompiledStatefulRun
78- }
75+ // statefulPrecompile implements the [PrecompiledContract] interface to allow a
76+ // [PrecompiledStatefulContract] to be carried with regular geth plumbing. The
77+ // methods are defined on this unexported type instead of directly on
78+ // [PrecompiledStatefulContract] to hide implementation details.
79+ type statefulPrecompile PrecompiledStatefulContract
7980
80- func ( p statefulPrecompile ) RequiredGas ( input [] byte ) uint64 {
81- return p . gas ( input )
82- }
81+ // RequiredGas always returns zero as this gas is consumed by native geth code
82+ // before the contract is run.
83+ func ( statefulPrecompile ) RequiredGas ([] byte ) uint64 { return 0 }
8384
8485func (p statefulPrecompile ) Run ([]byte ) ([]byte , error ) {
8586 // https://google.github.io/styleguide/go/best-practices.html#when-to-panic
8687 // This would indicate an API misuse and would occur in tests, not in
8788 // production.
88- panic (fmt .Sprintf ("BUG: call to %T.Run(); MUST call %T" , p , p . run ))
89+ panic (fmt .Sprintf ("BUG: call to %T.Run(); MUST call %T itself " , p , p ))
8990}
9091
9192// A PrecompileEnvironment provides information about the context in which a
0 commit comments