Skip to content

Commit bbc3b1b

Browse files
committed
feat: legacy package for backwards-compatible type support
1 parent 6170c14 commit bbc3b1b

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

core/vm/contracts.libevm_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/ava-labs/libevm/libevm"
4040
"github.com/ava-labs/libevm/libevm/ethtest"
4141
"github.com/ava-labs/libevm/libevm/hookstest"
42+
"github.com/ava-labs/libevm/libevm/legacy"
4243
"github.com/ava-labs/libevm/params"
4344
)
4445

@@ -146,16 +147,13 @@ func TestNewStatefulPrecompile(t *testing.T) {
146147
const gasLimit = 1e6
147148
gasCost := rng.Uint64n(gasLimit)
148149

149-
run := func(env vm.PrecompileEnvironment, input []byte) ([]byte, error) {
150+
run := func(env vm.PrecompileEnvironment, input []byte, suppliedGas uint64) ([]byte, uint64, error) {
150151
if got, want := env.StateDB() != nil, !env.ReadOnly(); got != want {
151-
return nil, fmt.Errorf("PrecompileEnvironment().StateDB() must be non-nil i.f.f. not read-only; got non-nil? %t; want %t", got, want)
152+
return nil, suppliedGas, fmt.Errorf("PrecompileEnvironment().StateDB() must be non-nil i.f.f. not read-only; got non-nil? %t; want %t", got, want)
152153
}
153154
hdr, err := env.BlockHeader()
154155
if err != nil {
155-
return nil, err
156-
}
157-
if !env.UseGas(gasCost) {
158-
return nil, vm.ErrOutOfGas
156+
return nil, suppliedGas, err
159157
}
160158

161159
out := &statefulPrecompileOutput{
@@ -169,11 +167,15 @@ func TestNewStatefulPrecompile(t *testing.T) {
169167
Input: input,
170168
IncomingCallType: env.IncomingCallType(),
171169
}
172-
return out.Bytes(), nil
170+
return out.Bytes(), suppliedGas - gasCost, nil
173171
}
174172
hooks := &hookstest.Stub{
175173
PrecompileOverrides: map[common.Address]libevm.PrecompiledContract{
176-
precompile: vm.NewStatefulPrecompile(run),
174+
precompile: vm.NewStatefulPrecompile(
175+
// In production, the new function signature should be used, but
176+
// this just exercises the converter.
177+
legacy.PrecompiledStatefulContract(run).Upgrade(),
178+
),
177179
},
178180
}
179181
hooks.Register(t)

libevm/legacy/legacy.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2024 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
// Package legacy provides converters between legacy types and their refactored
18+
// equivalents.
19+
package legacy
20+
21+
import "github.com/ava-labs/libevm/core/vm"
22+
23+
// PrecompiledStatefulContract is the legacy signature of
24+
// [vm.PrecompiledStatefulContract], which explicitly accepts and returns gas
25+
// values. Instances SHOULD NOT use the [vm.PrecompileEnvironment]
26+
// gas-management methods as this may result in unexpected behaviour.
27+
type PrecompiledStatefulContract func(env vm.PrecompileEnvironment, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error)
28+
29+
// Upgrade converts the legacy precompile signature into the now-required form.
30+
func (c PrecompiledStatefulContract) Upgrade() vm.PrecompiledStatefulContract {
31+
return func(env vm.PrecompileEnvironment, input []byte) ([]byte, error) {
32+
gas := env.Gas()
33+
ret, remainingGas, err := c(env, input, env.Gas())
34+
if used := gas - remainingGas; used < gas {
35+
env.UseGas(used)
36+
}
37+
return ret, err
38+
}
39+
}

0 commit comments

Comments
 (0)