diff --git a/go.work.sum b/go.work.sum index 52109fb0355b..c1cb374e0c0c 100644 --- a/go.work.sum +++ b/go.work.sum @@ -268,10 +268,13 @@ git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm9 github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 h1:gggzg0SUMs6SQbEw+3LoSsYf9YMjkupeAnHMX8O9mmY= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c= @@ -436,6 +439,7 @@ github.com/dgraph-io/badger v1.6.0 h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Ev github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d h1:W1n4DvpzZGOISgp7wWNtraLcHtnmnTwBlJidqtMIuwQ= github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= @@ -585,6 +589,7 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= @@ -760,12 +765,14 @@ github.com/phpdave11/gofpdi v1.0.13 h1:o61duiW8M9sMlkVXWlvP92sZJtGKENvW3VExs6dZu github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -951,11 +958,14 @@ golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5 h1:ObuXPmIgI4ZMyQLIz48cJYgSyWdjUXc2SZAdyJMwEAU= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -965,6 +975,7 @@ golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -990,6 +1001,7 @@ golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= @@ -1003,6 +1015,7 @@ golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1039,6 +1052,7 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go. google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs= +google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:WkJpQl6Ujj3ElX4qZaNm5t6cT95ffI4K+HKQ0+1NyMw= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= @@ -1050,6 +1064,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401001100-f93e5f3e9f0f/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v0.0.0-20170208002647-2a6bf6142e96/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= @@ -1059,8 +1075,10 @@ google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40Rmc google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0= +google.golang.org/grpc/examples v0.0.0-20250407062114-b368379ef8f6/go.mod h1:6ytKWczdvnpnO+m+JiG9NjEDzR1FJfsnmJdG7B8QVZ8= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/graft/coreth/core/BUILD.bazel b/graft/coreth/core/BUILD.bazel index 7dd78b5d47e8..2e1b84b3faf6 100644 --- a/graft/coreth/core/BUILD.bazel +++ b/graft/coreth/core/BUILD.bazel @@ -146,6 +146,7 @@ graft_go_test( "@com_github_ava_labs_libevm//common", "@com_github_ava_labs_libevm//common/math", "@com_github_ava_labs_libevm//consensus/misc/eip4844", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/rawdb", "@com_github_ava_labs_libevm//core/state", "@com_github_ava_labs_libevm//core/types", diff --git a/graft/coreth/core/bench_test.go b/graft/coreth/core/bench_test.go index 86d71b67ec3f..d9943aef5c49 100644 --- a/graft/coreth/core/bench_test.go +++ b/graft/coreth/core/bench_test.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/graft/coreth/params" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" @@ -90,7 +91,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) { return func(i int, gen *BlockGen) { toaddr := common.Address{} data := make([]byte, nbytes) - gas, _ := IntrinsicGas(data, nil, false, params.Rules{}) // Disable Istanbul and EIP-2028 for this test + gas, _ := ethcore.IntrinsicGas(data, nil, false, params.Rules{}) // Disable Istanbul and EIP-2028 for this test signer := gen.Signer() gasPrice := big.NewInt(0) if gen.header.BaseFee != nil { diff --git a/graft/coreth/core/error.go b/graft/coreth/core/error.go index bd78573d06d9..6995e1cc22e3 100644 --- a/graft/coreth/core/error.go +++ b/graft/coreth/core/error.go @@ -30,6 +30,7 @@ package core import ( "errors" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/types" ) @@ -78,7 +79,7 @@ var ( ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") // ErrGasUintOverflow is returned when calculating gas usage. - ErrGasUintOverflow = errors.New("gas uint64 overflow") + ErrGasUintOverflow = ethcore.ErrGasUintOverflow // ErrIntrinsicGas is returned if the transaction is specified to use less gas // than required to start the invocation. diff --git a/graft/coreth/core/predicate_check.go b/graft/coreth/core/predicate_check.go index f9ccb8d01705..1e1d5cfc4c3d 100644 --- a/graft/coreth/core/predicate_check.go +++ b/graft/coreth/core/predicate_check.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/graft/coreth/precompile/precompileconfig" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/evm/predicate" + + ethcore "github.com/ava-labs/libevm/core" ) var ErrMissingPredicateContext = errors.New("missing predicate context") @@ -51,7 +53,7 @@ func CheckTxPredicates( // Check that the transaction can cover its IntrinsicGas, including the gas // required by the predicate, before verifying the predicate. accessList := tx.AccessList() - intrinsicGas, err := IntrinsicGas(tx.Data(), accessList, tx.To() == nil, rules) + intrinsicGas, err := ethcore.IntrinsicGas(tx.Data(), accessList, tx.To() == nil, rules) if err != nil { return nil, err } diff --git a/graft/coreth/core/state_transition.go b/graft/coreth/core/state_transition.go index c7a545641a72..a62dc962d0b7 100644 --- a/graft/coreth/core/state_transition.go +++ b/graft/coreth/core/state_transition.go @@ -29,13 +29,12 @@ package core import ( "fmt" - "math" "math/big" "github.com/ava-labs/avalanchego/graft/coreth/params" - "github.com/ava-labs/avalanchego/vms/evm/predicate" "github.com/ava-labs/libevm/common" cmath "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" "github.com/ava-labs/libevm/crypto/kzg4844" @@ -80,112 +79,6 @@ func (result *ExecutionResult) Revert() []byte { return common.CopyBytes(result.ReturnData) } -// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, rules params.Rules) (uint64, error) { - // Set the starting gas for the raw transaction - var gas uint64 - if isContractCreation && rules.IsHomestead { - gas = ethparams.TxGasContractCreation - } else { - gas = ethparams.TxGas - } - dataLen := uint64(len(data)) - // Bump the required gas by the amount of transactional data - if dataLen > 0 { - // Zero and non-zero bytes are priced differently - var nz uint64 - for _, byt := range data { - if byt != 0 { - nz++ - } - } - // Make sure we don't exceed uint64 for all data combinations - nonZeroGas := ethparams.TxDataNonZeroGasFrontier - if rules.IsIstanbul { - nonZeroGas = ethparams.TxDataNonZeroGasEIP2028 - } - if (math.MaxUint64-gas)/nonZeroGas < nz { - return 0, ErrGasUintOverflow - } - gas += nz * nonZeroGas - - z := dataLen - nz - if (math.MaxUint64-gas)/ethparams.TxDataZeroGas < z { - return 0, ErrGasUintOverflow - } - gas += z * ethparams.TxDataZeroGas - - if isContractCreation && params.GetRulesExtra(rules).IsDurango { - lenWords := toWordSize(dataLen) - if (math.MaxUint64-gas)/ethparams.InitCodeWordGas < lenWords { - return 0, ErrGasUintOverflow - } - gas += lenWords * ethparams.InitCodeWordGas - } - } - if accessList != nil { - accessListGas, err := accessListGas(rules, accessList) - if err != nil { - return 0, err - } - totalGas, overflow := cmath.SafeAdd(gas, accessListGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } - - return gas, nil -} - -func accessListGas(rules params.Rules, accessList types.AccessList) (uint64, error) { - var gas uint64 - rulesExtra := params.GetRulesExtra(rules) - if !rulesExtra.PredicatersExist() { - gas += uint64(len(accessList)) * ethparams.TxAccessListAddressGas - gas += uint64(accessList.StorageKeys()) * ethparams.TxAccessListStorageKeyGas - return gas, nil - } - - for _, accessTuple := range accessList { - address := accessTuple.Address - predicaterContract, ok := rulesExtra.Predicaters[address] - if !ok { - // Previous access list gas calculation does not use safemath because an overflow would not be possible with - // the size of access lists that could be included in a block and standard access list gas costs. - // Therefore, we only check for overflow when adding to [totalGas], which could include the sum of values - // returned by a predicate. - accessTupleGas := ethparams.TxAccessListAddressGas + uint64(len(accessTuple.StorageKeys))*ethparams.TxAccessListStorageKeyGas - totalGas, overflow := cmath.SafeAdd(gas, accessTupleGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } else { - predicateGas, err := predicaterContract.PredicateGas(predicate.Predicate(accessTuple.StorageKeys), rulesExtra) - if err != nil { - return 0, err - } - totalGas, overflow := cmath.SafeAdd(gas, predicateGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } - } - - return gas, nil -} - -// toWordSize returns the ceiled word size required for init code payment calculation. -func toWordSize(size uint64) uint64 { - if size > math.MaxUint64-31 { - return math.MaxUint64/32 + 1 - } - - return (size + 31) / 32 -} - // A Message contains the data derived from a single transaction that is relevant to state // processing. type Message struct { @@ -457,7 +350,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { ) // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules) + gas, err := ethcore.IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules) if err != nil { return nil, err } diff --git a/graft/coreth/core/txpool/BUILD.bazel b/graft/coreth/core/txpool/BUILD.bazel index a869ab620085..25cb1f1eb487 100644 --- a/graft/coreth/core/txpool/BUILD.bazel +++ b/graft/coreth/core/txpool/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "//graft/coreth/core", "//graft/coreth/params", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/state", "@com_github_ava_labs_libevm//core/types", "@com_github_ava_labs_libevm//core/vm", diff --git a/graft/coreth/core/txpool/validation.go b/graft/coreth/core/txpool/validation.go index 49293147820f..22540be68946 100644 --- a/graft/coreth/core/txpool/validation.go +++ b/graft/coreth/core/txpool/validation.go @@ -35,6 +35,7 @@ import ( "github.com/ava-labs/avalanchego/graft/coreth/core" "github.com/ava-labs/avalanchego/graft/coreth/params" "github.com/ava-labs/libevm/common" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/state" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" @@ -121,7 +122,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, params.IsMergeTODO, head.Time)) + intrGas, err := ethcore.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, params.IsMergeTODO, head.Time)) if err != nil { return err } diff --git a/graft/coreth/params/BUILD.bazel b/graft/coreth/params/BUILD.bazel index f60eea3d788b..674e8a7bc1de 100644 --- a/graft/coreth/params/BUILD.bazel +++ b/graft/coreth/params/BUILD.bazel @@ -30,6 +30,8 @@ go_library( "//utils/set", "//vms/evm/predicate", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//common/math", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/vm", "@com_github_ava_labs_libevm//libevm", "@com_github_ava_labs_libevm//libevm/legacy", diff --git a/graft/coreth/params/hooks_libevm.go b/graft/coreth/params/hooks_libevm.go index 513ad930c10b..c4f0cacb77a5 100644 --- a/graft/coreth/params/hooks_libevm.go +++ b/graft/coreth/params/hooks_libevm.go @@ -24,6 +24,8 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/evm/predicate" + cmath "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" ethparams "github.com/ava-labs/libevm/params" ) @@ -54,9 +56,49 @@ func (RulesExtra) MinimumGasConsumption(x uint64) uint64 { return (ethparams.NOOPHooks{}).MinimumGasConsumption(x) } -// AccessListGas uses the default calculation. -func (RulesExtra) AccessListGas(accessList libevm.AccessList) (uint64, bool, error) { - return (ethparams.NOOPHooks{}).AccessListGas(accessList) +// AccessListGas computes the intrinsic gas for an access list. +// When predicaters exist, it calculates gas per-tuple, delegating to predicate +// contracts for addresses that have them. Otherwise, it returns override=false +// to use the default calculation. +func (r RulesExtra) AccessListGas(accessList libevm.AccessList) (uint64, bool, error) { + rules := extras.Rules(r) + if !rules.PredicatersExist() { + return 0, false, nil + } + return accessListGasWithPredicates(rules, accessList) +} + +// accessListGasWithPredicates calculates access list gas when predicaters exist. +// It handles both standard access tuples and predicate-based gas calculation. +func accessListGasWithPredicates(rules extras.Rules, accessList libevm.AccessList) (uint64, bool, error) { + var gas uint64 + for _, accessTuple := range accessList { + address := accessTuple.Address + predicaterContract, ok := rules.Predicaters[address] + if !ok { + // Previous access list gas calculation does not use safemath because an overflow would not be possible with + // the size of access lists that could be included in a block and standard access list gas costs. + // Therefore, we only check for overflow when adding to [totalGas], which could include the sum of values + // returned by a predicate. + accessTupleGas := ethparams.TxAccessListAddressGas + uint64(len(accessTuple.StorageKeys))*ethparams.TxAccessListStorageKeyGas + totalGas, overflow := cmath.SafeAdd(gas, accessTupleGas) + if overflow { + return 0, true, ethcore.ErrGasUintOverflow + } + gas = totalGas + } else { + predicateGas, err := predicaterContract.PredicateGas(predicate.Predicate(accessTuple.StorageKeys), rules) + if err != nil { + return 0, true, err + } + totalGas, overflow := cmath.SafeAdd(gas, predicateGas) + if overflow { + return 0, true, ethcore.ErrGasUintOverflow + } + gas = totalGas + } + } + return gas, true, nil } var PrecompiledContractsApricotPhase2 = map[common.Address]vm.PrecompiledContract{ diff --git a/graft/coreth/plugin/evm/BUILD.bazel b/graft/coreth/plugin/evm/BUILD.bazel index 30338fb4fd81..5fba0a853568 100644 --- a/graft/coreth/plugin/evm/BUILD.bazel +++ b/graft/coreth/plugin/evm/BUILD.bazel @@ -93,6 +93,7 @@ go_library( "//vms/evm/sync/customrawdb", "@com_github_ava_labs_firewood_go_ethhash_ffi//:ffi", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/rawdb", "@com_github_ava_labs_libevm//core/types", "@com_github_ava_labs_libevm//eth/tracers/js", diff --git a/graft/coreth/plugin/evm/wrapped_block.go b/graft/coreth/plugin/evm/wrapped_block.go index 853e563f3ffc..9f6dd751fe32 100644 --- a/graft/coreth/plugin/evm/wrapped_block.go +++ b/graft/coreth/plugin/evm/wrapped_block.go @@ -32,6 +32,8 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/utils/math" + + ethcore "github.com/ava-labs/libevm/core" ) var ( @@ -304,7 +306,7 @@ func (b *wrappedBlock) verifyIntrinsicGas() error { rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time()) var totalIntrinsicGasCost uint64 for _, tx := range b.ethBlock.Transactions() { - intrinsicGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, rules) + intrinsicGas, err := ethcore.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, rules) if err != nil { return fmt.Errorf("failed to calculate intrinsic gas: %w for tx %s", err, tx.Hash()) } diff --git a/graft/subnet-evm/core/BUILD.bazel b/graft/subnet-evm/core/BUILD.bazel index 1e2ee9c8c655..78c9fb58b7ff 100644 --- a/graft/subnet-evm/core/BUILD.bazel +++ b/graft/subnet-evm/core/BUILD.bazel @@ -156,6 +156,7 @@ graft_go_test( "@com_github_ava_labs_libevm//common", "@com_github_ava_labs_libevm//common/math", "@com_github_ava_labs_libevm//consensus/misc/eip4844", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/rawdb", "@com_github_ava_labs_libevm//core/state", "@com_github_ava_labs_libevm//core/types", diff --git a/graft/subnet-evm/core/bench_test.go b/graft/subnet-evm/core/bench_test.go index d14d3f2f48dd..e4dfcd395ee6 100644 --- a/graft/subnet-evm/core/bench_test.go +++ b/graft/subnet-evm/core/bench_test.go @@ -37,6 +37,7 @@ import ( "github.com/ava-labs/avalanchego/vms/evm/sync/customrawdb" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" @@ -91,7 +92,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) { return func(i int, gen *BlockGen) { toaddr := common.Address{} data := make([]byte, nbytes) - gas, _ := IntrinsicGas(data, nil, false, params.Rules{}) // Disable Istanbul and EIP-2028 for this test + gas, _ := ethcore.IntrinsicGas(data, nil, false, params.Rules{}) // Disable Istanbul and EIP-2028 for this test signer := gen.Signer() gasPrice := big.NewInt(0) if gen.header.BaseFee != nil { diff --git a/graft/subnet-evm/core/error.go b/graft/subnet-evm/core/error.go index bd78573d06d9..6995e1cc22e3 100644 --- a/graft/subnet-evm/core/error.go +++ b/graft/subnet-evm/core/error.go @@ -30,6 +30,7 @@ package core import ( "errors" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/types" ) @@ -78,7 +79,7 @@ var ( ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") // ErrGasUintOverflow is returned when calculating gas usage. - ErrGasUintOverflow = errors.New("gas uint64 overflow") + ErrGasUintOverflow = ethcore.ErrGasUintOverflow // ErrIntrinsicGas is returned if the transaction is specified to use less gas // than required to start the invocation. diff --git a/graft/subnet-evm/core/predicate_check.go b/graft/subnet-evm/core/predicate_check.go index e3435a87fae7..5b98b0b69c9e 100644 --- a/graft/subnet-evm/core/predicate_check.go +++ b/graft/subnet-evm/core/predicate_check.go @@ -14,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/graft/subnet-evm/precompile/precompileconfig" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/evm/predicate" + + ethcore "github.com/ava-labs/libevm/core" ) var ErrMissingPredicateContext = errors.New("missing predicate context") @@ -51,7 +53,7 @@ func CheckTxPredicates( // Check that the transaction can cover its IntrinsicGas, including the gas // required by the predicate, before verifying the predicate. accessList := tx.AccessList() - intrinsicGas, err := IntrinsicGas(tx.Data(), accessList, tx.To() == nil, rules) + intrinsicGas, err := ethcore.IntrinsicGas(tx.Data(), accessList, tx.To() == nil, rules) if err != nil { return nil, err } diff --git a/graft/subnet-evm/core/state_transition.go b/graft/subnet-evm/core/state_transition.go index 01dfc772d123..415a9860bdfc 100644 --- a/graft/subnet-evm/core/state_transition.go +++ b/graft/subnet-evm/core/state_transition.go @@ -29,15 +29,14 @@ package core import ( "fmt" - "math" "math/big" "github.com/ava-labs/avalanchego/graft/subnet-evm/params" "github.com/ava-labs/avalanchego/graft/subnet-evm/plugin/evm/vmerrors" "github.com/ava-labs/avalanchego/graft/subnet-evm/precompile/contracts/txallowlist" - "github.com/ava-labs/avalanchego/vms/evm/predicate" "github.com/ava-labs/libevm/common" cmath "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" "github.com/ava-labs/libevm/crypto/kzg4844" @@ -82,112 +81,6 @@ func (result *ExecutionResult) Revert() []byte { return common.CopyBytes(result.ReturnData) } -// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, rules params.Rules) (uint64, error) { - // Set the starting gas for the raw transaction - var gas uint64 - if isContractCreation && rules.IsHomestead { - gas = ethparams.TxGasContractCreation - } else { - gas = ethparams.TxGas - } - dataLen := uint64(len(data)) - // Bump the required gas by the amount of transactional data - if dataLen > 0 { - // Zero and non-zero bytes are priced differently - var nz uint64 - for _, byt := range data { - if byt != 0 { - nz++ - } - } - // Make sure we don't exceed uint64 for all data combinations - nonZeroGas := ethparams.TxDataNonZeroGasFrontier - if rules.IsIstanbul { - nonZeroGas = ethparams.TxDataNonZeroGasEIP2028 - } - if (math.MaxUint64-gas)/nonZeroGas < nz { - return 0, ErrGasUintOverflow - } - gas += nz * nonZeroGas - - z := dataLen - nz - if (math.MaxUint64-gas)/ethparams.TxDataZeroGas < z { - return 0, ErrGasUintOverflow - } - gas += z * ethparams.TxDataZeroGas - - if isContractCreation && params.GetRulesExtra(rules).IsDurango { - lenWords := toWordSize(dataLen) - if (math.MaxUint64-gas)/ethparams.InitCodeWordGas < lenWords { - return 0, ErrGasUintOverflow - } - gas += lenWords * ethparams.InitCodeWordGas - } - } - if accessList != nil { - accessListGas, err := accessListGas(rules, accessList) - if err != nil { - return 0, err - } - totalGas, overflow := cmath.SafeAdd(gas, accessListGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } - - return gas, nil -} - -func accessListGas(rules params.Rules, accessList types.AccessList) (uint64, error) { - var gas uint64 - rulesExtra := params.GetRulesExtra(rules) - if !rulesExtra.PredicatersExist() { - gas += uint64(len(accessList)) * ethparams.TxAccessListAddressGas - gas += uint64(accessList.StorageKeys()) * ethparams.TxAccessListStorageKeyGas - return gas, nil - } - - for _, accessTuple := range accessList { - address := accessTuple.Address - predicaterContract, ok := rulesExtra.Predicaters[address] - if !ok { - // Previous access list gas calculation does not use safemath because an overflow would not be possible with - // the size of access lists that could be included in a block and standard access list gas costs. - // Therefore, we only check for overflow when adding to [totalGas], which could include the sum of values - // returned by a predicate. - accessTupleGas := ethparams.TxAccessListAddressGas + uint64(len(accessTuple.StorageKeys))*ethparams.TxAccessListStorageKeyGas - totalGas, overflow := cmath.SafeAdd(gas, accessTupleGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } else { - predicateGas, err := predicaterContract.PredicateGas(predicate.Predicate(accessTuple.StorageKeys), rulesExtra) - if err != nil { - return 0, err - } - totalGas, overflow := cmath.SafeAdd(gas, predicateGas) - if overflow { - return 0, ErrGasUintOverflow - } - gas = totalGas - } - } - - return gas, nil -} - -// toWordSize returns the ceiled word size required for init code payment calculation. -func toWordSize(size uint64) uint64 { - if size > math.MaxUint64-31 { - return math.MaxUint64/32 + 1 - } - - return (size + 31) / 32 -} - // A Message contains the data derived from a single transaction that is relevant to state // processing. type Message struct { @@ -468,7 +361,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { ) // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules) + gas, err := ethcore.IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules) if err != nil { return nil, err } diff --git a/graft/subnet-evm/core/txpool/BUILD.bazel b/graft/subnet-evm/core/txpool/BUILD.bazel index ac97036c987c..d5aa103558ab 100644 --- a/graft/subnet-evm/core/txpool/BUILD.bazel +++ b/graft/subnet-evm/core/txpool/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//graft/subnet-evm/plugin/evm/vmerrors", "//graft/subnet-evm/precompile/contracts/txallowlist", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/state", "@com_github_ava_labs_libevm//core/types", "@com_github_ava_labs_libevm//core/vm", diff --git a/graft/subnet-evm/core/txpool/validation.go b/graft/subnet-evm/core/txpool/validation.go index 5eb64a33e7cb..18271929a745 100644 --- a/graft/subnet-evm/core/txpool/validation.go +++ b/graft/subnet-evm/core/txpool/validation.go @@ -37,6 +37,7 @@ import ( "github.com/ava-labs/avalanchego/graft/subnet-evm/plugin/evm/vmerrors" "github.com/ava-labs/avalanchego/graft/subnet-evm/precompile/contracts/txallowlist" "github.com/ava-labs/libevm/common" + ethcore "github.com/ava-labs/libevm/core" "github.com/ava-labs/libevm/core/state" "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/core/vm" @@ -123,7 +124,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, params.IsMergeTODO, head.Time)) + intrGas, err := ethcore.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, params.IsMergeTODO, head.Time)) if err != nil { return err } diff --git a/graft/subnet-evm/params/BUILD.bazel b/graft/subnet-evm/params/BUILD.bazel index 1b30cd777e4e..790f0b557769 100644 --- a/graft/subnet-evm/params/BUILD.bazel +++ b/graft/subnet-evm/params/BUILD.bazel @@ -29,6 +29,8 @@ go_library( "//utils/set", "//vms/evm/predicate", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//common/math", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/vm", "@com_github_ava_labs_libevm//libevm", "@com_github_ava_labs_libevm//libevm/legacy", diff --git a/graft/subnet-evm/params/hooks_libevm.go b/graft/subnet-evm/params/hooks_libevm.go index 3debb1f5d2fc..f2643dd9afbf 100644 --- a/graft/subnet-evm/params/hooks_libevm.go +++ b/graft/subnet-evm/params/hooks_libevm.go @@ -24,6 +24,8 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/evm/predicate" + cmath "github.com/ava-labs/libevm/common/math" + ethcore "github.com/ava-labs/libevm/core" ethparams "github.com/ava-labs/libevm/params" ) @@ -66,9 +68,49 @@ func (RulesExtra) MinimumGasConsumption(x uint64) uint64 { return (ethparams.NOOPHooks{}).MinimumGasConsumption(x) } -// AccessListGas uses the default calculation. -func (RulesExtra) AccessListGas(accessList libevm.AccessList) (uint64, bool, error) { - return (ethparams.NOOPHooks{}).AccessListGas(accessList) +// AccessListGas computes the intrinsic gas for an access list. +// When predicaters exist, it calculates gas per-tuple, delegating to predicate +// contracts for addresses that have them. Otherwise, it returns override=false +// to use the default calculation. +func (r RulesExtra) AccessListGas(accessList libevm.AccessList) (uint64, bool, error) { + rules := extras.Rules(r) + if !rules.PredicatersExist() { + return 0, false, nil + } + return accessListGasWithPredicates(rules, accessList) +} + +// accessListGasWithPredicates calculates access list gas when predicaters exist. +// It handles both standard access tuples and predicate-based gas calculation. +func accessListGasWithPredicates(rules extras.Rules, accessList libevm.AccessList) (uint64, bool, error) { + var gas uint64 + for _, accessTuple := range accessList { + address := accessTuple.Address + predicaterContract, ok := rules.Predicaters[address] + if !ok { + // Previous access list gas calculation does not use safemath because an overflow would not be possible with + // the size of access lists that could be included in a block and standard access list gas costs. + // Therefore, we only check for overflow when adding to [totalGas], which could include the sum of values + // returned by a predicate. + accessTupleGas := ethparams.TxAccessListAddressGas + uint64(len(accessTuple.StorageKeys))*ethparams.TxAccessListStorageKeyGas + totalGas, overflow := cmath.SafeAdd(gas, accessTupleGas) + if overflow { + return 0, true, ethcore.ErrGasUintOverflow + } + gas = totalGas + } else { + predicateGas, err := predicaterContract.PredicateGas(predicate.Predicate(accessTuple.StorageKeys), rules) + if err != nil { + return 0, true, err + } + totalGas, overflow := cmath.SafeAdd(gas, predicateGas) + if overflow { + return 0, true, ethcore.ErrGasUintOverflow + } + gas = totalGas + } + } + return gas, true, nil } var PrecompiledContractsGranite = map[common.Address]vm.PrecompiledContract{ diff --git a/graft/subnet-evm/plugin/evm/BUILD.bazel b/graft/subnet-evm/plugin/evm/BUILD.bazel index b95b93116d25..12b6c98dcabd 100644 --- a/graft/subnet-evm/plugin/evm/BUILD.bazel +++ b/graft/subnet-evm/plugin/evm/BUILD.bazel @@ -99,6 +99,7 @@ go_library( "//vms/evm/uptimetracker", "@com_github_ava_labs_firewood_go_ethhash_ffi//:ffi", "@com_github_ava_labs_libevm//common", + "@com_github_ava_labs_libevm//core", "@com_github_ava_labs_libevm//core/rawdb", "@com_github_ava_labs_libevm//core/types", "@com_github_ava_labs_libevm//eth/tracers/js", diff --git a/graft/subnet-evm/plugin/evm/wrapped_block.go b/graft/subnet-evm/plugin/evm/wrapped_block.go index e793a407d4bc..737715d3eb2f 100644 --- a/graft/subnet-evm/plugin/evm/wrapped_block.go +++ b/graft/subnet-evm/plugin/evm/wrapped_block.go @@ -28,6 +28,8 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/utils/math" + + ethcore "github.com/ava-labs/libevm/core" ) var ( @@ -262,7 +264,7 @@ func (b *wrappedBlock) verifyIntrinsicGas() error { rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time()) var totalIntrinsicGasCost uint64 for _, tx := range b.ethBlock.Transactions() { - intrinsicGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, rules) + intrinsicGas, err := ethcore.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, rules) if err != nil { return fmt.Errorf("failed to calculate intrinsic gas: %w for tx %s", err, tx.Hash()) }