Skip to content
Open
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
a620a92
refactor: use slices for precompile config test tables
JonathanOppenheimer Mar 19, 2026
f9588d3
build: add precompile interface and build
JonathanOppenheimer Jan 16, 2026
fcf11e7
feat: add acp224 precompile
JonathanOppenheimer Jan 16, 2026
c103b0f
fix: collisions and non zero
JonathanOppenheimer Jan 16, 2026
bc3cf91
refactor: use new spec
JonathanOppenheimer Mar 4, 2026
0b0f4ba
chore: new test error
JonathanOppenheimer Mar 4, 2026
7f1e2db
chore: unexport errors
JonathanOppenheimer Mar 4, 2026
ba6971d
chore: lint
JonathanOppenheimer Mar 4, 2026
ba9166f
chore: copilot review comments
JonathanOppenheimer Mar 4, 2026
fe02d3d
chore: lint
JonathanOppenheimer Mar 4, 2026
ab3cb77
chore: further hardcode address
JonathanOppenheimer Mar 4, 2026
9519ce0
chore: more address
JonathanOppenheimer Mar 4, 2026
b4138c6
chore: build bazel
JonathanOppenheimer Mar 17, 2026
786ade2
test: add tests
JonathanOppenheimer Mar 18, 2026
320adb2
chore: bazel
JonathanOppenheimer Mar 18, 2026
680e6f2
fix: remove invalid validation check
JonathanOppenheimer Mar 18, 2026
add6e93
Update graft/subnet-evm/commontype/fee_config.go
JonathanOppenheimer Mar 18, 2026
a0138f6
refactor: Cey feedback
JonathanOppenheimer Mar 18, 2026
3d440a2
chore: bazel
JonathanOppenheimer Mar 18, 2026
1fae150
chore: lint
JonathanOppenheimer Mar 18, 2026
317ca7f
refactor: tests + copilot feedback
JonathanOppenheimer Mar 18, 2026
446203c
fix: nil
JonathanOppenheimer Mar 18, 2026
24a7788
chore: claude nits
JonathanOppenheimer Mar 18, 2026
734067a
fix: nil fee config
JonathanOppenheimer Mar 18, 2026
a56e576
chore: revert
JonathanOppenheimer Mar 18, 2026
cfac83d
docs: godoc
JonathanOppenheimer Mar 18, 2026
1e0b887
chore: organize contract.go
JonathanOppenheimer Mar 18, 2026
4721e0d
test: use table
JonathanOppenheimer Mar 18, 2026
9eaaf02
chore: remove duplication verification
JonathanOppenheimer Mar 18, 2026
83763bc
chore: Cey review
JonathanOppenheimer Mar 19, 2026
316f2e8
fix: tests
JonathanOppenheimer Mar 19, 2026
c6d91d2
test: don't use init()
JonathanOppenheimer Mar 19, 2026
a27af0f
Revert "refactor: use slices for precompile config test tables"
JonathanOppenheimer Mar 20, 2026
b7c27a5
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 20, 2026
4e08c51
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 23, 2026
49691d4
chore: Cey review
JonathanOppenheimer Mar 25, 2026
d469314
Update graft/subnet-evm/precompile/contracts/acp224feemanager/config.go
JonathanOppenheimer Mar 25, 2026
de42e5d
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 25, 2026
bf26095
refactor: fall back to default config
JonathanOppenheimer Mar 25, 2026
14de17d
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 25, 2026
1ad2df6
chore: lint
JonathanOppenheimer Mar 25, 2026
ecad503
chore: lint
JonathanOppenheimer Mar 25, 2026
dc3a8e1
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 30, 2026
816351e
docs: add uint comment
JonathanOppenheimer Mar 30, 2026
79cd64e
docs: document per uint
JonathanOppenheimer Mar 31, 2026
23c83fa
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 31, 2026
4a0d14f
Update graft/subnet-evm/commontype/acp224_fee_config.go
JonathanOppenheimer Mar 31, 2026
095aa9b
Update graft/subnet-evm/commontype/acp224_fee_config.go
JonathanOppenheimer Mar 31, 2026
fb88e4d
Update graft/subnet-evm/commontype/acp224_fee_config.go
JonathanOppenheimer Mar 31, 2026
bf97714
chore: Austin review
JonathanOppenheimer Mar 31, 2026
da32c31
chore: bazel
JonathanOppenheimer Mar 31, 2026
5293c45
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Mar 31, 2026
13bd5a4
chore: lint
JonathanOppenheimer Mar 31, 2026
01cd7ce
chore: revert one Austin suggestion
JonathanOppenheimer Mar 31, 2026
a7d2595
chore: Austin comments
JonathanOppenheimer Apr 1, 2026
428e5a3
fix: nolint
JonathanOppenheimer Apr 1, 2026
b6c0ada
Update graft/subnet-evm/precompile/contracts/acp224feemanager/module.go
JonathanOppenheimer Apr 2, 2026
99067b2
chore: Arran feedback
JonathanOppenheimer Apr 2, 2026
eda0e76
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 2, 2026
4f3b020
fix: use uint64 directly
JonathanOppenheimer Apr 9, 2026
c2d66e0
chore: remove abi bridge code
JonathanOppenheimer Apr 9, 2026
3eb9e0c
chore: un-inline error
JonathanOppenheimer Apr 9, 2026
a4e1ab9
docs: precompile comments
JonathanOppenheimer Apr 9, 2026
42faaff
Update graft/subnet-evm/precompile/contracts/acp224feemanager/contrac…
JonathanOppenheimer Apr 9, 2026
c323071
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 9, 2026
c135ec5
Merge branch 'JonathanOppenheimer/acp224-add-precompile' of github.co…
JonathanOppenheimer Apr 9, 2026
2ac9012
Update graft/subnet-evm/commontype/acp224_fee_config_test.go
JonathanOppenheimer Apr 9, 2026
2e3d644
Merge branch 'JonathanOppenheimer/acp224-add-precompile' of github.co…
JonathanOppenheimer Apr 9, 2026
d089ed2
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 9, 2026
ed56a19
test: add ACP-224 fee manager simulated backend tests
JonathanOppenheimer Apr 10, 2026
cc2b7f9
docs: duplication
JonathanOppenheimer Apr 10, 2026
d465d46
Update graft/subnet-evm/commontype/acp224_fee_config_test.go
JonathanOppenheimer Apr 10, 2026
2a9bd38
Update graft/subnet-evm/commontype/acp224_fee_config_test.go
JonathanOppenheimer Apr 10, 2026
d0dbc94
Update graft/subnet-evm/commontype/acp224_fee_config_test.go
JonathanOppenheimer Apr 10, 2026
e30a9ed
Update graft/subnet-evm/precompile/contracts/acp224feemanager/config.go
JonathanOppenheimer Apr 10, 2026
6fd3b7f
chore: Arran review
JonathanOppenheimer Apr 10, 2026
2b7770a
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 10, 2026
4142b2f
chore: fix auto-apply
JonathanOppenheimer Apr 10, 2026
78d2129
fix: ordering + lint
JonathanOppenheimer Apr 10, 2026
09c8d2b
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 10, 2026
abbdb71
style: take 2
JonathanOppenheimer Apr 10, 2026
b074422
chore: Cey review
JonathanOppenheimer Apr 13, 2026
9d11237
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 13, 2026
ccd5efb
test: convert fuzz to table test
JonathanOppenheimer Apr 13, 2026
fd16177
chore: bazel
JonathanOppenheimer Apr 13, 2026
886df70
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 13, 2026
906252a
chore: lint
JonathanOppenheimer Apr 13, 2026
5e99002
test: properly fuzz graft targets
JonathanOppenheimer Apr 14, 2026
6d21d50
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 14, 2026
1f262ee
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 15, 2026
b990bb5
test: add fuzz corpora
JonathanOppenheimer Apr 15, 2026
4285c45
Merge branch 'JonathanOppenheimer/acp224-add-precompile' into Jonatha…
JonathanOppenheimer Apr 16, 2026
0d0c2e8
refactor: use a test contract
JonathanOppenheimer Apr 16, 2026
f8cdb17
chore: lint
JonathanOppenheimer Apr 16, 2026
6e293fe
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
ceyonur Apr 17, 2026
570a4d0
Merge branch 'master' into JonathanOppenheimer/acp224-add-precompile
JonathanOppenheimer Apr 27, 2026
30cf7f9
chore: bazel metadata
JonathanOppenheimer Apr 27, 2026
32d11ed
Merge branch 'JonathanOppenheimer/acp224-add-precompile' into Jonatha…
JonathanOppenheimer Apr 27, 2026
d3cd199
Merge remote-tracking branch 'origin/master' into JonathanOppenheimer…
JonathanOppenheimer May 6, 2026
a4bf037
chore: lint
JonathanOppenheimer May 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions graft/subnet-evm/commontype/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load("//.bazel:defs.bzl", "graft_go_test")
go_library(
name = "commontype",
srcs = [
"acp224_fee_config.go",
"fee_config.go",
"test_fee_config.go",
],
Expand All @@ -17,7 +18,13 @@ go_library(

graft_go_test(
name = "commontype_test",
srcs = ["fee_config_test.go"],
srcs = [
"acp224_fee_config_test.go",
"fee_config_test.go",
],
embed = [":commontype"],
deps = ["@com_github_stretchr_testify//require"],
deps = [
"//utils",
"@com_github_stretchr_testify//require",
],
)
111 changes: 111 additions & 0 deletions graft/subnet-evm/commontype/acp224_fee_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (C) 2019, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package commontype

import (
"encoding/binary"
"errors"

"github.com/ava-labs/libevm/common"
)

const MinTargetGasACP224 uint64 = 1_000_000

// DefaultACP224FeeConfig returns a copy of the default ACP-224 fee
// config.
//
// The default values are:
// - TargetGas: 1_000_000
// - MinGasPrice: 1
// - TimeToDouble: 60
func DefaultACP224FeeConfig() ACP224FeeConfig {
return ACP224FeeConfig{
TargetGas: 1_000_000,
MinGasPrice: 1,
TimeToDouble: 60,
}
}

var (
ErrMinGasPriceTooLow = errors.New("minGasPrice must be greater than 0")

ErrTargetGasMustBeZero = errors.New("targetGas must be 0 when validatorTargetGas is true")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We export these errors for use in the test.

ErrTargetGasTooLowACP224 = errors.New("targetGas must be at least MinTargetGasACP224")
ErrTimeToDoubleTooLow = errors.New("timeToDouble must be greater than 0")
ErrTimeToDoubleMustBeZero = errors.New("timeToDouble must be 0 when staticPricing is true")
)

// ACP224FeeConfig specifies the parameters for the ACP-224 dynamic gas limit mechanism.
// See [ACP224FeeConfig.Verify] for validation constraints between fields.
type ACP224FeeConfig struct {
ValidatorTargetGas bool `json:"validatorTargetGas,omitempty"` // when true, validators control targetGas via node preferences
TargetGas uint64 `json:"targetGas"` // target gas consumption per second
StaticPricing bool `json:"staticPricing,omitempty"` // when true, gas price is always minGasPrice
MinGasPrice uint64 `json:"minGasPrice"` // minimum gas price in wei
TimeToDouble uint64 `json:"timeToDouble"` // seconds for gas price to double at max capacity
}

// Verify returns an error if the config violates any field constraints.
func (a *ACP224FeeConfig) Verify() error {
switch {
case a.MinGasPrice == 0:
return ErrMinGasPriceTooLow
case a.ValidatorTargetGas && a.TargetGas != 0:
return ErrTargetGasMustBeZero
case !a.ValidatorTargetGas && a.TargetGas < MinTargetGasACP224:
return ErrTargetGasTooLowACP224
case a.StaticPricing && a.TimeToDouble != 0:
return ErrTimeToDoubleMustBeZero
case !a.StaticPricing && a.TimeToDouble == 0:
return ErrTimeToDoubleTooLow
default:
return nil
}
}

// Pack encodes the fee config into a single common.Hash (32 bytes).
//
// Layout (26 bytes used, 6 bytes padding):
//
// h[0] ValidatorTargetGas (bool)
// h[1:9] TargetGas (uint64)
// h[9] StaticPricing (bool)
// h[10:18] MinGasPrice (uint64)
// h[18:26] TimeToDouble (uint64)
func (a *ACP224FeeConfig) Pack() common.Hash {
var h common.Hash
put := binary.BigEndian.PutUint64

if a.ValidatorTargetGas {
h[0] = 1
}
put(h[1:], a.TargetGas)
if a.StaticPricing {
h[9] = 1
}
put(h[10:], a.MinGasPrice)
put(h[18:], a.TimeToDouble)
return h
}

// UnpackFrom decodes a packed common.Hash into the fee config fields.
// See [ACP224FeeConfig.Pack] for the byte layout.
func (a *ACP224FeeConfig) UnpackFrom(h common.Hash) {
u64 := binary.BigEndian.Uint64

a.ValidatorTargetGas = h[0] != 0
a.TargetGas = u64(h[1:])
a.StaticPricing = h[9] != 0
a.MinGasPrice = u64(h[10:])
a.TimeToDouble = u64(h[18:])
}

// Equal returns true if both configs are nil or have identical field values.
func (a *ACP224FeeConfig) Equal(other *ACP224FeeConfig) bool {
if a == nil || other == nil {
return a == other
}

return *a == *other
}
180 changes: 180 additions & 0 deletions graft/subnet-evm/commontype/acp224_fee_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright (C) 2019, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package commontype

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/utils"
)

func TestACP224FeeConfigVerify(t *testing.T) {
tests := []struct {
name string
config ACP224FeeConfig
want error
}{
{
name: "valid config",
config: DefaultACP224FeeConfig(),
},
{
name: "valid with validatorTargetGas",
config: ACP224FeeConfig{
ValidatorTargetGas: true,
MinGasPrice: 1,
TimeToDouble: 60,
},
},
{
name: "valid with staticPricing",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224,
StaticPricing: true,
MinGasPrice: 1,
},
},
{
name: "valid with both validatorTargetGas and staticPricing",
config: ACP224FeeConfig{
ValidatorTargetGas: true,
StaticPricing: true,
MinGasPrice: 1,
},
},
{
name: "minGasPrice zero",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224,
TimeToDouble: 60,
},
want: ErrMinGasPriceTooLow,
},
{
name: "targetGas must be zero when validatorTargetGas is true",
config: ACP224FeeConfig{
ValidatorTargetGas: true,
TargetGas: MinTargetGasACP224,
MinGasPrice: 1,
TimeToDouble: 60,
},
want: ErrTargetGasMustBeZero,
},
{
name: "targetGas below minimum",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224 - 1,
MinGasPrice: 1,
TimeToDouble: 60,
},
want: ErrTargetGasTooLowACP224,
},
{
name: "targetGas at minimum boundary",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224,
MinGasPrice: 1,
TimeToDouble: 1,
},
},
{
name: "timeToDouble must be zero when staticPricing is true",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224,
StaticPricing: true,
MinGasPrice: 1,
TimeToDouble: 60,
},
want: ErrTimeToDoubleMustBeZero,
},
{
name: "timeToDouble must be positive when staticPricing is false",
config: ACP224FeeConfig{
TargetGas: MinTargetGasACP224,
MinGasPrice: 1,
},
want: ErrTimeToDoubleTooLow,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Verify()
require.ErrorIs(t, err, tt.want, "Verify")
})
}
}

func FuzzACP224FeeConfigPacking(f *testing.F) {
for _, v := range []bool{true, false} {
for _, s := range []bool{true, false} {
for t := range uint64(3) {
for m := range uint64(3) {
for d := range uint64(3) {
f.Add(v, s, t, m, d)
}
}
}
}
}

f.Fuzz(func(t *testing.T, validator, static bool, target, minGas, double uint64) {
in := &ACP224FeeConfig{validator, target, static, minGas, double}
got := new(ACP224FeeConfig)
got.UnpackFrom(in.Pack())
require.Equalf(t, *in, *got, "%T.UnpackFrom(%[1]T.Pack()) round trip", in)
})
}

func TestACP224FeeConfigEqual(t *testing.T) {
tests := []struct {
name string
a *ACP224FeeConfig
b *ACP224FeeConfig
want bool
}{
{
name: "both equal",
a: utils.PointerTo(DefaultACP224FeeConfig()),
b: utils.PointerTo(DefaultACP224FeeConfig()),
want: true,
},
{
name: "different targetGas",
a: utils.PointerTo(DefaultACP224FeeConfig()),
b: func() *ACP224FeeConfig {
c := DefaultACP224FeeConfig()
c.TargetGas = 20_000_000
return &c
}(),
want: false,
},
{
name: "other nil",
a: utils.PointerTo(DefaultACP224FeeConfig()),
b: nil,
want: false,
},
{
name: "receiver nil",
a: nil,
b: utils.PointerTo(DefaultACP224FeeConfig()),
want: false,
},
{
name: "both nil",
a: nil,
b: nil,
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.want, tt.a.Equal(tt.b), "Equal()")
})
}
}
59 changes: 59 additions & 0 deletions graft/subnet-evm/precompile/contracts/acp224feemanager/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("//.bazel:defs.bzl", "graft_go_test")

go_library(
name = "acp224feemanager",
srcs = [
"config.go",
"contract.go",
"event.go",
"module.go",
],
embedsrcs = ["IACP224FeeManager.abi"],
importpath = "github.com/ava-labs/avalanchego/graft/subnet-evm/precompile/contracts/acp224feemanager",
visibility = ["//visibility:public"],
deps = [
"//graft/subnet-evm/commontype",
"//graft/subnet-evm/precompile/allowlist",
"//graft/subnet-evm/precompile/contract",
"//graft/subnet-evm/precompile/modules",
"//graft/subnet-evm/precompile/precompileconfig",
"@com_github_ava_labs_libevm//accounts/abi",
"@com_github_ava_labs_libevm//common",
"@com_github_ava_labs_libevm//core/types",
"@com_github_ava_labs_libevm//core/vm",
],
)

graft_go_test(
name = "acp224feemanager_test",
srcs = [
"config_test.go",
"contract_test.go",
"simulated_test.go",
],
embed = [":acp224feemanager"],
deps = [
"//graft/subnet-evm/accounts/abi/bind",
"//graft/subnet-evm/commontype",
"//graft/subnet-evm/core",
"//graft/subnet-evm/core/extstate",
"//graft/subnet-evm/ethclient/simulated",
"//graft/subnet-evm/params",
"//graft/subnet-evm/plugin/evm/customtypes",
"//graft/subnet-evm/precompile/allowlist",
"//graft/subnet-evm/precompile/allowlist/allowlisttest",
"//graft/subnet-evm/precompile/contract",
"//graft/subnet-evm/precompile/contracts/acp224feemanager/acp224feemanagertest/bindings",
"//graft/subnet-evm/precompile/contracts/utilstest",
"//graft/subnet-evm/precompile/modules",
"//graft/subnet-evm/precompile/precompileconfig",
"//graft/subnet-evm/precompile/precompiletest",
"//utils",
"@com_github_ava_labs_libevm//common",
"@com_github_ava_labs_libevm//core/vm",
"@com_github_ava_labs_libevm//crypto",
"@com_github_stretchr_testify//require",
"@org_uber_go_mock//gomock",
],
)
Loading
Loading