Merge tag 'v1.15.3' into release/geth-1.x-fh3.0

This commit is contained in:
Matthieu Vachon 2025-02-25 15:11:00 -05:00
commit fbf699a4c8
75 changed files with 797 additions and 1617 deletions

View file

@ -39,7 +39,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.23.0
go-version: 1.24.0
cache: false
- name: Run tests
run: go test -short ./...

View file

@ -25,7 +25,7 @@ linters:
- gocheckcompilerdirectives
- reassign
- mirror
- tenv
- usetesting
### linters we tried and will not be using:
###
# - structcheck # lots of false positives

View file

@ -15,7 +15,7 @@ jobs:
os: linux
arch: amd64
dist: focal
go: 1.23.x
go: 1.24.x
env:
- docker
services:
@ -33,7 +33,7 @@ jobs:
os: linux
dist: focal
sudo: required
go: 1.23.x
go: 1.24.x
env:
- azure-linux
git:
@ -85,7 +85,7 @@ jobs:
os: linux
arch: amd64
dist: focal
go: 1.23.x
go: 1.24.x
script:
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
@ -93,7 +93,7 @@ jobs:
if: type = push
os: linux
dist: focal
go: 1.22.x
go: 1.23.x
script:
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
@ -102,7 +102,7 @@ jobs:
if: type = cron || (type = push && tag ~= /^v[0-9]/)
os: linux
dist: focal
go: 1.23.x
go: 1.24.x
env:
- ubuntu-ppa
git:
@ -118,7 +118,7 @@ jobs:
if: type = cron
os: linux
dist: focal
go: 1.23.x
go: 1.24.x
env:
- azure-purge
git:
@ -131,7 +131,7 @@ jobs:
if: type = cron
os: linux
dist: focal
go: 1.23.x
go: 1.24.x
env:
- racetests
script:

View file

@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.23-alpine AS builder
FROM golang:1.24-alpine AS builder
RUN apk add --no-cache gcc musl-dev linux-headers git

View file

@ -4,7 +4,7 @@ ARG VERSION=""
ARG BUILDNUM=""
# Build Geth in a stock Go builder container
FROM golang:1.23-alpine AS builder
FROM golang:1.24-alpine AS builder
RUN apk add --no-cache gcc musl-dev linux-headers git

View file

@ -16,7 +16,7 @@ archives are published at https://geth.ethereum.org/downloads/.
For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth).
Building `geth` requires both a Go (version 1.22 or later) and a C compiler. You can install
Building `geth` requires both a Go (version 1.23 or later) and a C compiler. You can install
them using your favourite package manager. Once the dependencies are installed, run
```shell

View file

@ -5,82 +5,109 @@
# https://github.com/ethereum/execution-spec-tests/releases/download/pectra-devnet-6%40v1.0.0/fixtures_pectra-devnet-6.tar.gz
b69211752a3029083c020dc635fe12156ca1a6725a08559da540a0337586a77e fixtures_pectra-devnet-6.tar.gz
# version:golang 1.23.6
# version:golang 1.24.0
# https://go.dev/dl/
039c5b04e65279daceee8a6f71e70bd05cf5b801782b6f77c6e19e2ed0511222 go1.23.6.src.tar.gz
adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c go1.23.6.aix-ppc64.tar.gz
782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0 go1.23.6.darwin-amd64.tar.gz
5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221 go1.23.6.darwin-arm64.tar.gz
d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb go1.23.6.dragonfly-amd64.tar.gz
d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7 go1.23.6.freebsd-386.tar.gz
ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6 go1.23.6.freebsd-amd64.tar.gz
b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6 go1.23.6.freebsd-arm.tar.gz
004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310 go1.23.6.freebsd-arm64.tar.gz
ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a go1.23.6.freebsd-riscv64.tar.gz
7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8 go1.23.6.illumos-amd64.tar.gz
e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba go1.23.6.linux-386.tar.gz
9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d go1.23.6.linux-amd64.tar.gz
561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202 go1.23.6.linux-arm64.tar.gz
27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74 go1.23.6.linux-armv6l.tar.gz
c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750 go1.23.6.linux-loong64.tar.gz
e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622 go1.23.6.linux-mips.tar.gz
7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f go1.23.6.linux-mips64.tar.gz
74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a go1.23.6.linux-mips64le.tar.gz
09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb go1.23.6.linux-mipsle.tar.gz
5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c go1.23.6.linux-ppc64.tar.gz
0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99 go1.23.6.linux-ppc64le.tar.gz
f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3 go1.23.6.linux-riscv64.tar.gz
321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e go1.23.6.linux-s390x.tar.gz
92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c go1.23.6.netbsd-386.tar.gz
86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c go1.23.6.netbsd-amd64.tar.gz
4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816 go1.23.6.netbsd-arm.tar.gz
53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9 go1.23.6.netbsd-arm64.tar.gz
6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9 go1.23.6.openbsd-386.tar.gz
f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae go1.23.6.openbsd-amd64.tar.gz
3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f go1.23.6.openbsd-arm.tar.gz
cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c go1.23.6.openbsd-arm64.tar.gz
64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602 go1.23.6.openbsd-ppc64.tar.gz
c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377 go1.23.6.openbsd-riscv64.tar.gz
10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01 go1.23.6.plan9-386.tar.gz
9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f go1.23.6.plan9-amd64.tar.gz
8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83 go1.23.6.plan9-arm.tar.gz
b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7 go1.23.6.solaris-amd64.tar.gz
96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8 go1.23.6.windows-386.zip
53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243 go1.23.6.windows-amd64.zip
22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218 go1.23.6.windows-arm.zip
a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41 go1.23.6.windows-arm64.zip
d14120614acb29d12bcab72bd689f257eb4be9e0b6f88a8fb7e41ac65f8556e5 go1.24.0.src.tar.gz
5d04588154d5923bd8e26b76111806340ec55c41af1b05623ea744fcb3d6bc22 go1.24.0.aix-ppc64.tar.gz
7af054e5088b68c24b3d6e135e5ca8d91bbd5a05cb7f7f0187367b3e6e9e05ee go1.24.0.darwin-amd64.tar.gz
dee0ea64411a00b47ded586d5a8e30cfe3acf51564aa1bb24e039a6dca807a29 go1.24.0.darwin-amd64.pkg
fd9cfb5dd6c75a347cfc641a253f0db1cebaca16b0dd37965351c6184ba595e4 go1.24.0.darwin-arm64.tar.gz
b19eb6b7ae87f8371c3e7a84d129db67779a2883d2fffa6bb90412b0167df133 go1.24.0.darwin-arm64.pkg
d0dc34ad86aea746abe245994c68a9e1ad8f46ba8c4af901cd5861a4dd4c21df go1.24.0.dragonfly-amd64.tar.gz
4ee02b1f3812aff4da79c79464ee4038ca61ad74b3a9619850f30435f81c2536 go1.24.0.freebsd-386.tar.gz
838191001f9324da904dece35a586a3156d548687db87ac9461aa3d38fc88b09 go1.24.0.freebsd-amd64.tar.gz
ce6ad4e84a40a8a1d848b7e31b0cddfd1cee8f7959e7dc358a8fa8b5566ea718 go1.24.0.freebsd-arm.tar.gz
511f7b0cac4c4ed1066d324072ce223b906ad6b2a85f2e1c5d260eb7d08b5901 go1.24.0.freebsd-arm64.tar.gz
a1e4072630dc589a2975ef51317b52c7d8599bf6f389fc59033c01e0a0fa705a go1.24.0.freebsd-riscv64.tar.gz
7593e9dcee9f07c3df6d099f7d259f5734a6c0dccc5f28962f18e7f501c9bb21 go1.24.0.illumos-amd64.tar.gz
90521453a59c6ce20364d2dc7c38532949b033b602ba12d782caeb90af1b0624 go1.24.0.linux-386.tar.gz
dea9ca38a0b852a74e81c26134671af7c0fbe65d81b0dc1c5bfe22cf7d4c8858 go1.24.0.linux-amd64.tar.gz
c3fa6d16ffa261091a5617145553c71d21435ce547e44cc6dfb7470865527cc7 go1.24.0.linux-arm64.tar.gz
695dc54fa14cd3124fa6900d7b5ae39eeac23f7a4ecea81656070160fac2c54a go1.24.0.linux-armv6l.tar.gz
a201e4c9b7e6d29ed64c43296ed88e81a66f82f2093ce45b766d2c526941396f go1.24.0.linux-loong64.tar.gz
f3ac039aae78ad0bfb08106406c2e62eaf763dd82ebaf0ecd539adadd1d729a6 go1.24.0.linux-mips.tar.gz
f2e6456d45e024831b1da8d88b1bb6392cca9500c1b00841f525d76c9e9553e0 go1.24.0.linux-mips64.tar.gz
b847893ff119389c939adc2b8516b6500204b7cb49d5e19b25e1c2091d2c74c6 go1.24.0.linux-mips64le.tar.gz
bd4aed27d02746c237c3921e97029ac6b6fe687a67436b8f52ff1f698d330bd9 go1.24.0.linux-mipsle.tar.gz
007123c9b06c41729a4bb3f166f4df7196adf4e33c2d2ab0e7e990175f0ce1d4 go1.24.0.linux-ppc64.tar.gz
a871a43de7d26c91dd90cb6e0adacb214c9e35ee2188c617c91c08c017efe81a go1.24.0.linux-ppc64le.tar.gz
620dcf48c6297519aad6c81f8e344926dc0ab09a2a79f1e306964aece95a553d go1.24.0.linux-riscv64.tar.gz
544d78b077c6b54bf78958c4a8285abec2d21f668fb007261c77418cd2edbb46 go1.24.0.linux-s390x.tar.gz
8b143a7edefbaa2a0b0246c9df2df1bac9fbed909d8615a375c08da7744e697d go1.24.0.netbsd-386.tar.gz
67150a6dd7bdb9c4e88d77f46ee8c4dc99d5e71deca4912d8c2c85f7a16d0262 go1.24.0.netbsd-amd64.tar.gz
446b2539f11218fd6f6f6e3dd90b20ae55a06afe129885eeb3df51eb344eb0f6 go1.24.0.netbsd-arm.tar.gz
370115b6ff7d30b29431223de348eb11ab65e3c92627532d97fd55f63f94e7a8 go1.24.0.netbsd-arm64.tar.gz
cbda5f15f06ed9630f122a53542d9de13d149643633c74f1dcb45e79649b788a go1.24.0.openbsd-386.tar.gz
926f601d0e655ab1e8d7f357fd82542e5cf206c38c4e2f9fccf0706987d38836 go1.24.0.openbsd-amd64.tar.gz
8a54892f8c933c541fff144a825d0fdc41bae14b0832aab703cb75eb4cb64f2c go1.24.0.openbsd-arm.tar.gz
ef7fddcef0a22c7900c178b7687cf5aa25c2a9d46a3cc330b77a6de6e6c2396b go1.24.0.openbsd-arm64.tar.gz
b3b5e2e2b53489ded2c2c21900ddcbbdb7991632bb5b42f05f125d71675e0b76 go1.24.0.openbsd-ppc64.tar.gz
fbcb1dbf1269b4079dc4fd0b15f3274b9d635f1a7e319c3fc1a907b03280348e go1.24.0.openbsd-riscv64.tar.gz
33b4221e1c174a16e3f661deab6c60838ac4ae6cb869a4da1d1115773ceed88b go1.24.0.plan9-386.tar.gz
111a89014019cdbd69c2978de9b3e201f77e35183c8ab3606fba339d38f28549 go1.24.0.plan9-amd64.tar.gz
8da3d3997049f40ebe0cd336a9bb9e4bfa4832df3c90a32f07383371d6d74849 go1.24.0.plan9-arm.tar.gz
b6069da21dc95ccdbd047675b584e5480ffc3eba35f9e7c8b0e7b317aaf01e2c go1.24.0.solaris-amd64.tar.gz
b53c28a4c2863ec50ab4a1dbebe818ef6177f86773b6f43475d40a5d9aa4ec9e go1.24.0.windows-386.zip
f07677013cd7861c5e16067b0a82144c23c4bf72c139c762e142440f4c926f61 go1.24.0.windows-386.msi
96b7280979205813759ee6947be7e3bb497da85c482711116c00522e3bb41ff1 go1.24.0.windows-amd64.zip
4e78016d889431eb16aa0f87868cf52479b90059791c94a4ff45872d0573089e go1.24.0.windows-amd64.msi
53f73450fb66075d16be9f206e9177bd972b528168271918c4747903b5596c3d go1.24.0.windows-arm64.zip
4f9780158fb7996dcbcbc7c7ef208f880b5e8c1f2792ba3ede0c75050c1bc23a go1.24.0.windows-arm64.msi
# version:golangci 1.63.4
# version:golangci 1.64.4
# https://github.com/golangci/golangci-lint/releases/
# https://github.com/golangci/golangci-lint/releases/download/v1.63.4/
878d017cc360e4fb19510d39852c8189852e3c48e7ce0337577df73507c97d68 golangci-lint-1.63.4-darwin-amd64.tar.gz
a2b630c2ac8466393f0ccbbede4462387b6c190697a70bc2298c6d2123f21bbf golangci-lint-1.63.4-darwin-arm64.tar.gz
8938b74aa92888e561a1c5a4c175110b92f84e7d24733703e6d9ebc39e9cd5f8 golangci-lint-1.63.4-freebsd-386.tar.gz
054903339d620df2e760b978920100986e3b03bcb058f669d520a71dac9c34ed golangci-lint-1.63.4-freebsd-amd64.tar.gz
a19d499f961a02608348e8b626537a88edfaab6e1b6534f1eff742b5d6d750e4 golangci-lint-1.63.4-freebsd-armv6.tar.gz
00d616f0fb275b780ce4d26604bdd7fdbfe6bc9c63acd5a0b31498e1f7511108 golangci-lint-1.63.4-freebsd-armv7.tar.gz
d453688e0eabded3c1a97ff5a2777bb0df5a18851efdaaaf6b472e3e5713c33e golangci-lint-1.63.4-illumos-amd64.tar.gz
6b1bec847fc9f347d53712d05606a49d55d0e3b5c1bacadfed2393f3503de0e9 golangci-lint-1.63.4-linux-386.tar.gz
01abb14a4df47b5ca585eff3c34b105023cba92ec34ff17212dbb83855581690 golangci-lint-1.63.4-linux-amd64.tar.gz
51f0c79d19a92353e0465fb30a4901a0644a975d34e6f399ad2eebc0160bbb24 golangci-lint-1.63.4-linux-arm64.tar.gz
8d0a43f41e8424fbae10f7aa2dc29999f98112817c6dba63d7dc76832940a673 golangci-lint-1.63.4-linux-armv6.tar.gz
1045a047b31e9302c9160c7b0f199f4ac1bd02a1b221a2d9521bd3507f0cf671 golangci-lint-1.63.4-linux-armv7.tar.gz
933fe10ab50ce3bb0806e15a4ae69fe20f0549abf91dea0161236000ca706e67 golangci-lint-1.63.4-linux-loong64.tar.gz
45798630cbad5642862766051199fa862ef3c33d569cab12f01cac4f68e2ddd5 golangci-lint-1.63.4-linux-mips64.tar.gz
86ae25335ddb24975d2c915c1af0c7fad70dce99d0b4614fa4bee392de714aa2 golangci-lint-1.63.4-linux-mips64le.tar.gz
33dabd11aaba4b602938da98bcf49aabab55019557e0115cdc3dbcc3009768fa golangci-lint-1.63.4-linux-ppc64le.tar.gz
4e7a81230a663bcdf30bba5689ce96040abc76994dbc2003dce32c8dca8c06f3 golangci-lint-1.63.4-linux-riscv64.tar.gz
21370b49c7c47f4d9b8f982c952f940b01e65710174c3b4dad7b6452d58f92ec golangci-lint-1.63.4-linux-s390x.tar.gz
255866a6464c7e11bb7edd8e6e6ad54f11e1f01b82ba9ca229698ac788cd9724 golangci-lint-1.63.4-netbsd-386.tar.gz
2798c040ac658bda97224f204795199c81ac97bb207b21c02b664aaed380d5d2 golangci-lint-1.63.4-netbsd-amd64.tar.gz
b910eecffd0064103837e7e1abe870deb8ade22331e6dffe319f430d49399c8e golangci-lint-1.63.4-netbsd-arm64.tar.gz
df2693ef37147b457c3e2089614537dd2ae2e18e53641e756a5b404f4c72d3fa golangci-lint-1.63.4-netbsd-armv6.tar.gz
a28a533366974bd7834c4516cd6075bff3419a508d1ed7aa63ae8182768b352e golangci-lint-1.63.4-netbsd-armv7.tar.gz
368932775fb5c620b324dabf018155f3365f5e33c5af5b26e9321db373f96eea golangci-lint-1.63.4-windows-386.zip
184d13c2b8f5441576bec2a0d8ba7b2d45445595cf796b879a73bcc98c39f8c1 golangci-lint-1.63.4-windows-amd64.zip
4fabf175d5b05ef0858ded49527948eebac50e9093814979fd84555a75fb80a6 golangci-lint-1.63.4-windows-arm64.zip
e92be3f3ff30d4a849fb4b9a4c8d56837dee45269cb405a3ecad52fa034c781b golangci-lint-1.63.4-windows-armv6.zip
c71d348653b8f7fbb109bb10c1a481722bc6b0b2b6e731b897f99ac869f7653e golangci-lint-1.63.4-windows-armv7.zip
# https://github.com/golangci/golangci-lint/releases/download/v1.64.4/
f31ef6e20c62acc31eb7b851d611b4bd10256d1b1d8be38f0cceec300b5b60db golangci-lint-1.64.4-darwin-amd64.tar.gz
bb4a9ece7ef66ef49bd6de873f5f5ec801cf93dacf58efb360cc939b4fd37c47 golangci-lint-1.64.4-darwin-arm64.tar.gz
fd8f9046150356e36ad8af31f99219515d5e0ff6e8e9f4204182312447018fcf golangci-lint-1.64.4-freebsd-386.tar.gz
bbae940caa31cb1d2d8d26abd867666cd92746d2ddc63d6917d128c456d715ef golangci-lint-1.64.4-freebsd-amd64.tar.gz
86eb00cbdc5e277857a380d556d78a42b3edf8aae5991de8767dce7da337d73b golangci-lint-1.64.4-freebsd-armv6.tar.gz
c0f7d50f4fcd39ae8bda181c127b078a79d87c885ac472c4cce5b01134dde5bc golangci-lint-1.64.4-freebsd-armv7.tar.gz
31d264fa26a73a583425bc9b39c18de70a330e346fe800e80c277ddb5f8477b6 golangci-lint-1.64.4-illumos-amd64.tar.gz
3dccc18a6b1a0f2518196190ed56277b1480b381231605936eca6b862426b83c golangci-lint-1.64.4-linux-386.deb
b95f3e757c59ada75144bd086478ab63bcda83c2b2a935e60d8f39aff20fbcd2 golangci-lint-1.64.4-linux-386.rpm
8fa58af0022ae0487162c02d08075e2d869c9b5f8613a64b85fd769a2a2d2b93 golangci-lint-1.64.4-linux-386.tar.gz
fa80d2ad920fc74b85a0b93ad1671fd27c9c4d6f22e167cc4e1da758d72dd893 golangci-lint-1.64.4-linux-amd64.deb
8bf2e3c82504a893a12e84ecbc8071f787075d2fdc1ef946deda3d29aae1afad golangci-lint-1.64.4-linux-amd64.rpm
7de8f80a12cd3052610e6be21f08f2220805b1f3e43b3b6ec843f14a12140de2 golangci-lint-1.64.4-linux-amd64.tar.gz
ade222b9ae997a2875e44ed53ca5a129f24944b232132d0a5898f101381d3bfa golangci-lint-1.64.4-linux-arm64.deb
8f9f8617ed0d8b8f62c8dfe69877932c0d85f0d83a9ec3250b04777c7133ada1 golangci-lint-1.64.4-linux-arm64.rpm
debf1f73e71f1dd288957574eab4e7515b1b04c4ac2f127192181da8a42f0e8e golangci-lint-1.64.4-linux-arm64.tar.gz
3f616caa4a16738114ad29076a333c62bb0650fe4846b438c341d235f78ee5aa golangci-lint-1.64.4-linux-armv6.deb
6a7c9d7b7c57d7d440e1e3f133e18e4b5b703604d4ae7f7862fb9ea461887a8b golangci-lint-1.64.4-linux-armv6.rpm
d7b9e3c89af93d98c6b5a555ef48e25bee24f84d7825a29e343e9966404d5b4d golangci-lint-1.64.4-linux-armv6.tar.gz
18179ecf04ace3051450852424b31a4d26644a3912e759cd595e624eee0174bd golangci-lint-1.64.4-linux-armv7.deb
f669fce85d3edc3d557d1e64e2241d895f1ee676f79d139874bf76693cc447a2 golangci-lint-1.64.4-linux-armv7.rpm
9bbaa13b474ecb1560fb05aee0a8cab3e9cc327d41632bee8b553b766f2bf756 golangci-lint-1.64.4-linux-armv7.tar.gz
b5a2725adba2a1b04a5160ffa0730ba30b88c1ee99ecbc65dd7075a8d70f3730 golangci-lint-1.64.4-linux-loong64.deb
28ac00afb3f6407808fe7c15a6002e5fe6b3b461df3fe0223603542e6f9b974a golangci-lint-1.64.4-linux-loong64.rpm
121170309fed82cb64d6fae5020ef2b194e591a53156370c221a80121cc4aa08 golangci-lint-1.64.4-linux-loong64.tar.gz
aadfaab41380f53ada8f7ad4fa9af784bb882eaaa1e3939e048b3a5ea8f2c13f golangci-lint-1.64.4-linux-mips64.deb
6fecbff69086e316dd028050d3ebf82fc466c7f4dc0f6084307054621101c202 golangci-lint-1.64.4-linux-mips64.rpm
430c48034527af028dc608c115166f47b6b67c8cb83a317d9d44876b9753292a golangci-lint-1.64.4-linux-mips64.tar.gz
432126af2bbbd639dbbcc2c265337f104cc613a7b4c5a8fb5e49f182b428f077 golangci-lint-1.64.4-linux-mips64le.deb
cfa663eee0fae721510d6dc31e61db4be51b4e4244eb7de2b6a9bc6d475551e5 golangci-lint-1.64.4-linux-mips64le.rpm
2bacfac65182893c5ceb67b61d5b9d2b24da47726d84cb87d734a6e32f040148 golangci-lint-1.64.4-linux-mips64le.tar.gz
66d86e47d68420c03045eff0698e9acf9f82d97cd1f07d7e52837a6e544eceed golangci-lint-1.64.4-linux-ppc64le.deb
05466bd2d8e82f7245b838e29d0c90cdbaf67375b2b5bc980d8510d5edb206ad golangci-lint-1.64.4-linux-ppc64le.rpm
e013b6980f7140712af0aedc9a661265e1d3c6adc7e9d045734e3686a3601acc golangci-lint-1.64.4-linux-ppc64le.tar.gz
753980d2fb421d35292b71b51f9bb0552f18de2eb181ccf692ef79e086ad2304 golangci-lint-1.64.4-linux-riscv64.deb
73a33a883020298f8c652a4ace4f6888103d80d411fe3e9b77ce0a3b36ff7d3a golangci-lint-1.64.4-linux-riscv64.rpm
020efd09b894dc75012f43b1d4c58e69e5446ca3f79845b5e10a02588def3e1b golangci-lint-1.64.4-linux-riscv64.tar.gz
4d99a16bc9ff5cea5e4ae3568c6254390fbdad8f1d370c287744409112bceff9 golangci-lint-1.64.4-linux-s390x.deb
6e63374a9f95fc09f2bb9501059eb18b8107e08416722ba7b561ae385d80b33b golangci-lint-1.64.4-linux-s390x.rpm
62a6febb892b26eee84a32cc99d04afe90bf62d0970774b1bab75e36b66f53b4 golangci-lint-1.64.4-linux-s390x.tar.gz
5ba4d235f9abd60d2d280f9fe4228c6ddab11ae9fe48d253b7e477046675f1f6 golangci-lint-1.64.4-netbsd-386.tar.gz
061643bb4370a52010e5e76f88f5b5220e51058df50af86b45286263af92b321 golangci-lint-1.64.4-netbsd-amd64.tar.gz
12b2be6c35bcf7a36374e952c7efec7905a17fa3ebe6214924ba8721b766c4af golangci-lint-1.64.4-netbsd-arm64.tar.gz
553a71a677751dccee082ed8afe24cf58bef725f72aa02aedcc6758dd8f44125 golangci-lint-1.64.4-netbsd-armv6.tar.gz
74a5a5a7b8c8cd11dccdec303ee6592d904b09836782e6d658be359737f300ef golangci-lint-1.64.4-netbsd-armv7.tar.gz
b3ceea2187843f9ba6510303141a72465621e3f190a262c0b48707b9e983ea9a golangci-lint-1.64.4-source.tar.gz
fda4de312fcb0b4853b03bcdfb31ac631a68fa0b966f6aa010eb30d14427180b golangci-lint-1.64.4-windows-386.zip
8fc60bd809f86c6431ed8f3d1f25917538c0ebc93e670cfb199f25bbaa56e602 golangci-lint-1.64.4-windows-amd64.zip
b9058c9d2ae8d75048c6ad8885d11e5ac0a6c40be2af85bfa6605e48d69d3eb6 golangci-lint-1.64.4-windows-arm64.zip
809b0131adb1aa8b359becd13222df367b505bc2955bb3b1d2d0dd6f07347b13 golangci-lint-1.64.4-windows-armv6.zip
fc43f8c95d6bec8ba9a3557a0bb63cf9f504137ce6d24cfdc4c330d46f7779d2 golangci-lint-1.64.4-windows-armv7.zip
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
#

View file

@ -94,7 +94,7 @@ type Account struct {
> Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such, the Client would not be aware of any errors (like e.g. "Invalid params","Internal error"
### 3.1.0
* Add `ContentType` `string` to `SignDataRequest` to accommodate the latest EIP-191 and EIP-712 implementations.
* Add `ContentType` `string` to `SignDataRequest` to accommodate the latest [EIP-191](https://eips.ethereum.org/EIPS/eip-191) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) implementations.
### 3.0.0

View file

@ -57,13 +57,7 @@ func TestMain(m *testing.M) {
// This method creates a temporary keystore folder which will be removed after
// the test exits.
func runClef(t *testing.T, args ...string) *testproc {
ddir, err := os.MkdirTemp("", "cleftest-*")
if err != nil {
return nil
}
t.Cleanup(func() {
os.RemoveAll(ddir)
})
ddir := t.TempDir()
return runWithKeystore(t, ddir, args...)
}

View file

@ -262,7 +262,7 @@ var (
}
StateHistoryFlag = &cli.Uint64Flag{
Name: "history.state",
Usage: "Number of recent blocks to retain state history for (default = 90,000 blocks, 0 = entire chain)",
Usage: "Number of recent blocks to retain state history for, only relevant in state.scheme=path (default = 90,000 blocks, 0 = entire chain)",
Value: ethconfig.Defaults.StateHistory,
Category: flags.StateCategory,
}

View file

@ -87,11 +87,7 @@ func TestHistoryImportAndExport(t *testing.T) {
}
// Make temp directory for era files.
dir, err := os.MkdirTemp("", "history-export-test")
if err != nil {
t.Fatalf("error creating temp test directory: %v", err)
}
defer os.RemoveAll(dir)
dir := t.TempDir()
// Export history to temp directory.
if err := ExportHistory(chain, dir, 0, count, step); err != nil {

View file

@ -83,6 +83,8 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTim
func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int {
var frac uint64
switch config.LatestFork(header.Time) {
case forks.Osaka:
frac = config.BlobScheduleConfig.Osaka.UpdateFraction
case forks.Prague:
frac = config.BlobScheduleConfig.Prague.UpdateFraction
case forks.Cancun:
@ -103,6 +105,8 @@ func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
s = cfg.BlobScheduleConfig
)
switch {
case cfg.IsOsaka(london, time) && s.Osaka != nil:
return s.Osaka.Max
case cfg.IsPrague(london, time) && s.Prague != nil:
return s.Prague.Max
case cfg.IsCancun(london, time) && s.Cancun != nil:
@ -125,6 +129,8 @@ func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int {
return 0
}
switch {
case s.Osaka != nil:
return s.Osaka.Max
case s.Prague != nil:
return s.Prague.Max
case s.Cancun != nil:
@ -144,6 +150,8 @@ func targetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
s = cfg.BlobScheduleConfig
)
switch {
case cfg.IsOsaka(london, time) && s.Osaka != nil:
return s.Osaka.Target
case cfg.IsPrague(london, time) && s.Prague != nil:
return s.Prague.Target
case cfg.IsCancun(london, time) && s.Cancun != nil:

View file

@ -1,156 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package asm provides support for dealing with EVM assembly instructions (e.g., disassembling them).
package asm
import (
"encoding/hex"
"fmt"
"github.com/ethereum/go-ethereum/core/vm"
)
// Iterator for disassembled EVM instructions
type instructionIterator struct {
code []byte
pc uint64
arg []byte
op vm.OpCode
error error
started bool
eofEnabled bool
}
// NewInstructionIterator creates a new instruction iterator.
func NewInstructionIterator(code []byte) *instructionIterator {
it := new(instructionIterator)
it.code = code
return it
}
// NewEOFInstructionIterator creates a new instruction iterator for EOF-code.
func NewEOFInstructionIterator(code []byte) *instructionIterator {
it := NewInstructionIterator(code)
it.eofEnabled = true
return it
}
// Next returns true if there is a next instruction and moves on.
func (it *instructionIterator) Next() bool {
if it.error != nil || uint64(len(it.code)) <= it.pc {
// We previously reached an error or the end.
return false
}
if it.started {
// Since the iteration has been already started we move to the next instruction.
if it.arg != nil {
it.pc += uint64(len(it.arg))
}
it.pc++
} else {
// We start the iteration from the first instruction.
it.started = true
}
if uint64(len(it.code)) <= it.pc {
// We reached the end.
return false
}
it.op = vm.OpCode(it.code[it.pc])
var a int
if !it.eofEnabled { // Legacy code
if it.op.IsPush() {
a = int(it.op) - int(vm.PUSH0)
}
} else { // EOF code
if it.op == vm.RJUMPV {
// RJUMPV is unique as it has a variable sized operand. The total size is
// determined by the count byte which immediately follows RJUMPV.
maxIndex := int(it.code[it.pc+1])
a = (maxIndex+1)*2 + 1
} else {
a = vm.Immediates(it.op)
}
}
if a > 0 {
u := it.pc + 1 + uint64(a)
if uint64(len(it.code)) <= it.pc || uint64(len(it.code)) < u {
it.error = fmt.Errorf("incomplete instruction at %v", it.pc)
return false
}
it.arg = it.code[it.pc+1 : u]
} else {
it.arg = nil
}
return true
}
// Error returns any error that may have been encountered.
func (it *instructionIterator) Error() error {
return it.error
}
// PC returns the PC of the current instruction.
func (it *instructionIterator) PC() uint64 {
return it.pc
}
// Op returns the opcode of the current instruction.
func (it *instructionIterator) Op() vm.OpCode {
return it.op
}
// Arg returns the argument of the current instruction.
func (it *instructionIterator) Arg() []byte {
return it.arg
}
// PrintDisassembled pretty-print all disassembled EVM instructions to stdout.
func PrintDisassembled(code string) error {
script, err := hex.DecodeString(code)
if err != nil {
return err
}
it := NewInstructionIterator(script)
for it.Next() {
if it.Arg() != nil && 0 < len(it.Arg()) {
fmt.Printf("%05x: %v %#x\n", it.PC(), it.Op(), it.Arg())
} else {
fmt.Printf("%05x: %v\n", it.PC(), it.Op())
}
}
return it.Error()
}
// Disassemble returns all disassembled EVM instructions in human-readable format.
func Disassemble(script []byte) ([]string, error) {
instrs := make([]string, 0)
it := NewInstructionIterator(script)
for it.Next() {
if it.Arg() != nil && 0 < len(it.Arg()) {
instrs = append(instrs, fmt.Sprintf("%05x: %v %#x\n", it.PC(), it.Op(), it.Arg()))
} else {
instrs = append(instrs, fmt.Sprintf("%05x: %v\n", it.PC(), it.Op()))
}
}
if err := it.Error(); err != nil {
return nil, err
}
return instrs, nil
}

View file

@ -1,94 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package asm
import (
"encoding/hex"
"fmt"
"strings"
"testing"
)
// Tests disassembling instructions
func TestInstructionIterator(t *testing.T) {
for i, tc := range []struct {
code string
legacyWant string
eofWant string
}{
{"", "", ""}, // empty
{"6100", `err: incomplete instruction at 0`, `err: incomplete instruction at 0`},
{"61000000", `
00000: PUSH2 0x0000
00003: STOP`, `
00000: PUSH2 0x0000
00003: STOP`},
{"5F00", `
00000: PUSH0
00001: STOP`, `
00000: PUSH0
00001: STOP`},
{"d1aabb00", `00000: DATALOADN
00001: opcode 0xaa not defined
00002: opcode 0xbb not defined
00003: STOP`, `
00000: DATALOADN 0xaabb
00003: STOP`}, // DATALOADN(aabb),STOP
{"d1aa", `
00000: DATALOADN
00001: opcode 0xaa not defined`, "err: incomplete instruction at 0\n"}, // DATALOADN(aa) invalid
{"e20211223344556600", `
00000: RJUMPV
00001: MUL
00002: GT
00003: opcode 0x22 not defined
00004: CALLER
00005: DIFFICULTY
00006: SSTORE
err: incomplete instruction at 7`, `
00000: RJUMPV 0x02112233445566
00008: STOP`}, // RJUMPV( 6 bytes), STOP
} {
var (
code, _ = hex.DecodeString(tc.code)
legacy = strings.TrimSpace(disassembly(NewInstructionIterator(code)))
eof = strings.TrimSpace(disassembly(NewEOFInstructionIterator(code)))
)
if want := strings.TrimSpace(tc.legacyWant); legacy != want {
t.Errorf("test %d: wrong (legacy) output. have:\n%q\nwant:\n%q\n", i, legacy, want)
}
if want := strings.TrimSpace(tc.eofWant); eof != want {
t.Errorf("test %d: wrong (eof) output. have:\n%q\nwant:\n%q\n", i, eof, want)
}
}
}
func disassembly(it *instructionIterator) string {
var out = new(strings.Builder)
for it.Next() {
if it.Arg() != nil && 0 < len(it.Arg()) {
fmt.Fprintf(out, "%05x: %v %#x\n", it.PC(), it.Op(), it.Arg())
} else {
fmt.Fprintf(out, "%05x: %v\n", it.PC(), it.Op())
}
}
if err := it.Error(); err != nil {
fmt.Fprintf(out, "err: %v\n", err)
}
return out.String()
}

View file

@ -1,292 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package asm
import (
"encoding/hex"
"errors"
"fmt"
"math/big"
"os"
"strings"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/vm"
)
// Compiler contains information about the parsed source
// and holds the tokens for the program.
type Compiler struct {
tokens []token
out []byte
labels map[string]int
pc, pos int
debug bool
}
// NewCompiler returns a new allocated compiler.
func NewCompiler(debug bool) *Compiler {
return &Compiler{
labels: make(map[string]int),
debug: debug,
}
}
// Feed feeds tokens into ch and are interpreted by
// the compiler.
//
// feed is the first pass in the compile stage as it collects the used labels in the
// program and keeps a program counter which is used to determine the locations of the
// jump dests. The labels can than be used in the second stage to push labels and
// determine the right position.
func (c *Compiler) Feed(ch <-chan token) {
var prev token
for i := range ch {
switch i.typ {
case number:
num := math.MustParseBig256(i.text).Bytes()
if len(num) == 0 {
num = []byte{0}
}
c.pc += len(num)
case stringValue:
c.pc += len(i.text) - 2
case element:
c.pc++
case labelDef:
c.labels[i.text] = c.pc
c.pc++
case label:
c.pc += 4
if prev.typ == element && isJump(prev.text) {
c.pc++
}
}
c.tokens = append(c.tokens, i)
prev = i
}
if c.debug {
fmt.Fprintln(os.Stderr, "found", len(c.labels), "labels")
}
}
// Compile compiles the current tokens and returns a binary string that can be interpreted
// by the EVM and an error if it failed.
//
// compile is the second stage in the compile phase which compiles the tokens to EVM
// instructions.
func (c *Compiler) Compile() (string, []error) {
var errors []error
// continue looping over the tokens until
// the stack has been exhausted.
for c.pos < len(c.tokens) {
if err := c.compileLine(); err != nil {
errors = append(errors, err)
}
}
// turn the binary to hex
h := hex.EncodeToString(c.out)
return h, errors
}
// next returns the next token and increments the
// position.
func (c *Compiler) next() token {
token := c.tokens[c.pos]
c.pos++
return token
}
// compileLine compiles a single line instruction e.g.
// "push 1", "jump @label".
func (c *Compiler) compileLine() error {
n := c.next()
if n.typ != lineStart {
return compileErr(n, n.typ.String(), lineStart.String())
}
lvalue := c.next()
switch lvalue.typ {
case eof:
return nil
case element:
if err := c.compileElement(lvalue); err != nil {
return err
}
case labelDef:
c.compileLabel()
case lineEnd:
return nil
default:
return compileErr(lvalue, lvalue.text, fmt.Sprintf("%v or %v", labelDef, element))
}
if n := c.next(); n.typ != lineEnd {
return compileErr(n, n.text, lineEnd.String())
}
return nil
}
// parseNumber compiles the number to bytes
func parseNumber(tok token) ([]byte, error) {
if tok.typ != number {
panic("parseNumber of non-number token")
}
num, ok := math.ParseBig256(tok.text)
if !ok {
return nil, errors.New("invalid number")
}
bytes := num.Bytes()
if len(bytes) == 0 {
bytes = []byte{0}
}
return bytes, nil
}
// compileElement compiles the element (push & label or both)
// to a binary representation and may error if incorrect statements
// where fed.
func (c *Compiler) compileElement(element token) error {
switch {
case isJump(element.text):
return c.compileJump(element.text)
case isPush(element.text):
return c.compilePush()
default:
c.outputOpcode(toBinary(element.text))
return nil
}
}
func (c *Compiler) compileJump(jumpType string) error {
rvalue := c.next()
switch rvalue.typ {
case number:
numBytes, err := parseNumber(rvalue)
if err != nil {
return err
}
c.outputBytes(numBytes)
case stringValue:
// strings are quoted, remove them.
str := rvalue.text[1 : len(rvalue.text)-2]
c.outputBytes([]byte(str))
case label:
c.outputOpcode(vm.PUSH4)
pos := big.NewInt(int64(c.labels[rvalue.text])).Bytes()
pos = append(make([]byte, 4-len(pos)), pos...)
c.outputBytes(pos)
case lineEnd:
// push without argument is supported, it just takes the destination from the stack.
c.pos--
default:
return compileErr(rvalue, rvalue.text, "number, string or label")
}
// push the operation
c.outputOpcode(toBinary(jumpType))
return nil
}
func (c *Compiler) compilePush() error {
// handle pushes. pushes are read from left to right.
var value []byte
rvalue := c.next()
switch rvalue.typ {
case number:
value = math.MustParseBig256(rvalue.text).Bytes()
if len(value) == 0 {
value = []byte{0}
}
case stringValue:
value = []byte(rvalue.text[1 : len(rvalue.text)-1])
case label:
value = big.NewInt(int64(c.labels[rvalue.text])).Bytes()
value = append(make([]byte, 4-len(value)), value...)
default:
return compileErr(rvalue, rvalue.text, "number, string or label")
}
if len(value) > 32 {
return fmt.Errorf("%d: string or number size > 32 bytes", rvalue.lineno+1)
}
c.outputOpcode(vm.OpCode(int(vm.PUSH1) - 1 + len(value)))
c.outputBytes(value)
return nil
}
// compileLabel pushes a jumpdest to the binary slice.
func (c *Compiler) compileLabel() {
c.outputOpcode(vm.JUMPDEST)
}
func (c *Compiler) outputOpcode(op vm.OpCode) {
if c.debug {
fmt.Printf("%d: %v\n", len(c.out), op)
}
c.out = append(c.out, byte(op))
}
// output pushes the value v to the binary stack.
func (c *Compiler) outputBytes(b []byte) {
if c.debug {
fmt.Printf("%d: %x\n", len(c.out), b)
}
c.out = append(c.out, b...)
}
// isPush returns whether the string op is either any of
// push(N).
func isPush(op string) bool {
return strings.EqualFold(op, "PUSH")
}
// isJump returns whether the string op is jump(i)
func isJump(op string) bool {
return strings.EqualFold(op, "JUMPI") || strings.EqualFold(op, "JUMP")
}
// toBinary converts text to a vm.OpCode
func toBinary(text string) vm.OpCode {
return vm.StringToOp(strings.ToUpper(text))
}
type compileError struct {
got string
want string
lineno int
}
func (err compileError) Error() string {
return fmt.Sprintf("%d: syntax error: unexpected %v, expected %v", err.lineno, err.got, err.want)
}
func compileErr(c token, got, want string) error {
return compileError{
got: got,
want: want,
lineno: c.lineno + 1,
}
}

View file

@ -1,79 +0,0 @@
// Copyright 2019 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package asm
import (
"testing"
)
func TestCompiler(t *testing.T) {
tests := []struct {
input, output string
}{
{
input: `
GAS
label:
PUSH @label
`,
output: "5a5b6300000001",
},
{
input: `
PUSH @label
label:
`,
output: "63000000055b",
},
{
input: `
PUSH @label
JUMP
label:
`,
output: "6300000006565b",
},
{
input: `
JUMP @label
label:
`,
output: "6300000006565b",
},
{
input: `
JUMP @label
label: ;; comment
ADD ;; comment
`,
output: "6300000006565b01",
},
}
for _, test := range tests {
ch := Lex([]byte(test.input), false)
c := NewCompiler(false)
c.Feed(ch)
output, err := c.Compile()
if len(err) != 0 {
t.Errorf("compile error: %v\ninput: %s", err, test.input)
continue
}
if output != test.output {
t.Errorf("incorrect output\ninput: %sgot: %s\nwant: %s\n", test.input, output, test.output)
}
}
}

View file

@ -1,93 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package asm
import (
"reflect"
"testing"
)
func lexAll(src string) []token {
ch := Lex([]byte(src), false)
var tokens []token
for i := range ch {
tokens = append(tokens, i)
}
return tokens
}
func TestLexer(t *testing.T) {
tests := []struct {
input string
tokens []token
}{
{
input: ";; this is a comment",
tokens: []token{{typ: lineStart}, {typ: eof}},
},
{
input: "0x12345678",
tokens: []token{{typ: lineStart}, {typ: number, text: "0x12345678"}, {typ: eof}},
},
{
input: "0x123ggg",
tokens: []token{{typ: lineStart}, {typ: number, text: "0x123"}, {typ: element, text: "ggg"}, {typ: eof}},
},
{
input: "12345678",
tokens: []token{{typ: lineStart}, {typ: number, text: "12345678"}, {typ: eof}},
},
{
input: "123abc",
tokens: []token{{typ: lineStart}, {typ: number, text: "123"}, {typ: element, text: "abc"}, {typ: eof}},
},
{
input: "0123abc",
tokens: []token{{typ: lineStart}, {typ: number, text: "0123"}, {typ: element, text: "abc"}, {typ: eof}},
},
{
input: "00123abc",
tokens: []token{{typ: lineStart}, {typ: number, text: "00123"}, {typ: element, text: "abc"}, {typ: eof}},
},
{
input: "@foo",
tokens: []token{{typ: lineStart}, {typ: label, text: "foo"}, {typ: eof}},
},
{
input: "@label123",
tokens: []token{{typ: lineStart}, {typ: label, text: "label123"}, {typ: eof}},
},
// Comment after label
{
input: "@label123 ;; comment",
tokens: []token{{typ: lineStart}, {typ: label, text: "label123"}, {typ: eof}},
},
// Comment after instruction
{
input: "push 3 ;; comment\nadd",
tokens: []token{{typ: lineStart}, {typ: element, text: "push"}, {typ: number, text: "3"}, {typ: lineEnd, text: "\n"}, {typ: lineStart, lineno: 1}, {typ: element, lineno: 1, text: "add"}, {typ: eof, lineno: 1}},
},
}
for _, test := range tests {
tokens := lexAll(test.input)
if !reflect.DeepEqual(tokens, test.tokens) {
t.Errorf("input %q\ngot: %+v\nwant: %+v", test.input, tokens, test.tokens)
}
}
}

View file

@ -1,275 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package asm
import (
"fmt"
"os"
"strings"
"unicode"
"unicode/utf8"
)
// stateFn is used through the lifetime of the
// lexer to parse the different values at the
// current state.
type stateFn func(*lexer) stateFn
// token is emitted when the lexer has discovered
// a new parsable token. These are delivered over
// the tokens channels of the lexer
type token struct {
typ tokenType
lineno int
text string
}
// tokenType are the different types the lexer
// is able to parse and return.
type tokenType int
//go:generate go run golang.org/x/tools/cmd/stringer -type tokenType
const (
eof tokenType = iota // end of file
lineStart // emitted when a line starts
lineEnd // emitted when a line ends
invalidStatement // any invalid statement
element // any element during element parsing
label // label is emitted when a label is found
labelDef // label definition is emitted when a new label is found
number // number is emitted when a number is found
stringValue // stringValue is emitted when a string has been found
)
const (
decimalNumbers = "1234567890" // characters representing any decimal number
hexNumbers = decimalNumbers + "aAbBcCdDeEfF" // characters representing any hexadecimal
alpha = "abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ" // characters representing alphanumeric
)
// lexer is the basic construct for parsing
// source code and turning them in to tokens.
// Tokens are interpreted by the compiler.
type lexer struct {
input string // input contains the source code of the program
tokens chan token // tokens is used to deliver tokens to the listener
state stateFn // the current state function
lineno int // current line number in the source file
start, pos, width int // positions for lexing and returning value
debug bool // flag for triggering debug output
}
// Lex lexes the program by name with the given source. It returns a
// channel on which the tokens are delivered.
func Lex(source []byte, debug bool) <-chan token {
ch := make(chan token)
l := &lexer{
input: string(source),
tokens: ch,
state: lexLine,
debug: debug,
}
go func() {
l.emit(lineStart)
for l.state != nil {
l.state = l.state(l)
}
l.emit(eof)
close(l.tokens)
}()
return ch
}
// next returns the next rune in the program's source.
func (l *lexer) next() (rune rune) {
if l.pos >= len(l.input) {
l.width = 0
return 0
}
rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
l.pos += l.width
return rune
}
// backup backsup the last parsed element (multi-character)
func (l *lexer) backup() {
l.pos -= l.width
}
// peek returns the next rune but does not advance the seeker
func (l *lexer) peek() rune {
r := l.next()
l.backup()
return r
}
// ignore advances the seeker and ignores the value
func (l *lexer) ignore() {
l.start = l.pos
}
// accept checks whether the given input matches the next rune
func (l *lexer) accept(valid string) bool {
if strings.ContainsRune(valid, l.next()) {
return true
}
l.backup()
return false
}
// acceptRun will continue to advance the seeker until valid
// can no longer be met.
func (l *lexer) acceptRun(valid string) {
for strings.ContainsRune(valid, l.next()) {
}
l.backup()
}
// acceptRunUntil is the inverse of acceptRun and will continue
// to advance the seeker until the rune has been found.
func (l *lexer) acceptRunUntil(until rune) bool {
// Continues running until a rune is found
for i := l.next(); !strings.ContainsRune(string(until), i); i = l.next() {
if i == 0 {
return false
}
}
return true
}
// blob returns the current value
func (l *lexer) blob() string {
return l.input[l.start:l.pos]
}
// Emits a new token on to token channel for processing
func (l *lexer) emit(t tokenType) {
token := token{t, l.lineno, l.blob()}
if l.debug {
fmt.Fprintf(os.Stderr, "%04d: (%-20v) %s\n", token.lineno, token.typ, token.text)
}
l.tokens <- token
l.start = l.pos
}
// lexLine is state function for lexing lines
func lexLine(l *lexer) stateFn {
for {
switch r := l.next(); {
case r == '\n':
l.emit(lineEnd)
l.ignore()
l.lineno++
l.emit(lineStart)
case r == ';' && l.peek() == ';':
return lexComment
case isSpace(r):
l.ignore()
case isLetter(r) || r == '_':
return lexElement
case isNumber(r):
return lexNumber
case r == '@':
l.ignore()
return lexLabel
case r == '"':
return lexInsideString
default:
return nil
}
}
}
// lexComment parses the current position until the end
// of the line and discards the text.
func lexComment(l *lexer) stateFn {
l.acceptRunUntil('\n')
l.backup()
l.ignore()
return lexLine
}
// lexLabel parses the current label, emits and returns
// the lex text state function to advance the parsing
// process.
func lexLabel(l *lexer) stateFn {
l.acceptRun(alpha + "_" + decimalNumbers)
l.emit(label)
return lexLine
}
// lexInsideString lexes the inside of a string until
// the state function finds the closing quote.
// It returns the lex text state function.
func lexInsideString(l *lexer) stateFn {
if l.acceptRunUntil('"') {
l.emit(stringValue)
}
return lexLine
}
func lexNumber(l *lexer) stateFn {
acceptance := decimalNumbers
if l.accept("xX") {
acceptance = hexNumbers
}
l.acceptRun(acceptance)
l.emit(number)
return lexLine
}
func lexElement(l *lexer) stateFn {
l.acceptRun(alpha + "_" + decimalNumbers)
if l.peek() == ':' {
l.emit(labelDef)
l.accept(":")
l.ignore()
} else {
l.emit(element)
}
return lexLine
}
func isLetter(t rune) bool {
return unicode.IsLetter(t)
}
func isSpace(t rune) bool {
return unicode.IsSpace(t)
}
func isNumber(t rune) bool {
return unicode.IsNumber(t)
}

View file

@ -1,31 +0,0 @@
// Code generated by "stringer -type tokenType"; DO NOT EDIT.
package asm
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[eof-0]
_ = x[lineStart-1]
_ = x[lineEnd-2]
_ = x[invalidStatement-3]
_ = x[element-4]
_ = x[label-5]
_ = x[labelDef-6]
_ = x[number-7]
_ = x[stringValue-8]
}
const _tokenType_name = "eoflineStartlineEndinvalidStatementelementlabellabelDefnumberstringValue"
var _tokenType_index = [...]uint8{0, 3, 12, 19, 35, 42, 47, 55, 61, 72}
func (i tokenType) String() string {
if i < 0 || i >= tokenType(len(_tokenType_index)-1) {
return "tokenType(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _tokenType_name[_tokenType_index[i]:_tokenType_index[i+1]]
}

View file

@ -281,6 +281,7 @@ func TestVerkleGenesisCommit(t *testing.T) {
BlobScheduleConfig: &params.BlobScheduleConfig{
Cancun: params.DefaultCancunBlobConfig,
Prague: params.DefaultPragueBlobConfig,
Osaka: params.DefaultOsakaBlobConfig,
Verkle: params.DefaultPragueBlobConfig,
},
}

View file

@ -229,7 +229,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM) {
}
evm.SetTxContext(NewEVMTxContext(msg))
evm.StateDB.AddAddressToAccessList(params.BeaconRootsAddress)
_, _, _ = evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
_, _, _ = evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560)
evm.StateDB.Finalise(true)
}
@ -253,7 +253,7 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM) {
}
evm.SetTxContext(NewEVMTxContext(msg))
evm.StateDB.AddAddressToAccessList(params.HistoryStorageAddress)
_, _, err := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
_, _, err := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560)
if err != nil {
panic(err)
}
@ -292,7 +292,7 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte
}
evm.SetTxContext(NewEVMTxContext(msg))
evm.StateDB.AddAddressToAccessList(addr)
ret, _, _ := evm.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
ret, _, _ := evm.Call(msg.From, *msg.To, msg.Data, 30_000_000, common.U2560)
evm.StateDB.Finalise(true)
if len(ret) == 0 {
return // skip empty output

View file

@ -423,7 +423,6 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
var (
msg = st.msg
sender = vm.AccountRef(msg.From)
rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time)
contractCreation = msg.To == nil
floorDataGas uint64
@ -484,7 +483,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
)
if contractCreation {
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, value)
ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value)
} else {
// Increment the nonce for the next transaction.
st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1, tracing.NonceChangeEoACall)
@ -507,7 +506,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
}
// Execute the transaction's call.
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, value)
ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value)
}
// Compute refund counter, capped to a refund quotient.

View file

@ -21,6 +21,7 @@ import (
"crypto/ecdsa"
"crypto/sha256"
"errors"
"fmt"
"math"
"math/big"
"os"
@ -452,8 +453,7 @@ func TestOpenDrops(t *testing.T) {
//log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil)
@ -775,8 +775,7 @@ func TestOpenIndex(t *testing.T) {
//log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil)
@ -864,8 +863,7 @@ func TestOpenHeap(t *testing.T) {
//log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil)
@ -951,8 +949,7 @@ func TestOpenCap(t *testing.T) {
//log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil)
@ -1041,8 +1038,7 @@ func TestChangingSlotterSize(t *testing.T) {
//log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(6), nil)
@ -1508,8 +1504,7 @@ func TestAdd(t *testing.T) {
}
for i, tt := range tests {
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage) // late defer, still ok
storage := filepath.Join(t.TempDir(), fmt.Sprintf("test-%d", i))
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil)

View file

@ -51,22 +51,9 @@ var (
// making the transaction invalid, rather a DOS protection.
ErrOversizedData = errors.New("oversized data")
// ErrFutureReplacePending is returned if a future transaction replaces a pending
// one. Future transactions should only be able to replace other future transactions.
ErrFutureReplacePending = errors.New("future transaction tries to replace pending")
// ErrAlreadyReserved is returned if the sender address has a pending transaction
// in a different subpool. For example, this error is returned in response to any
// input transaction of non-blob type when a blob transaction from this sender
// remains pending (and vice-versa).
ErrAlreadyReserved = errors.New("address already reserved")
// ErrAuthorityReserved is returned if a transaction has an authorization
// signed by an address which already has in-flight transactions known to the
// pool.
ErrAuthorityReserved = errors.New("authority already reserved")
// ErrAuthorityNonce is returned if a transaction has an authorization with
// a nonce that is not currently valid for the authority.
ErrAuthorityNonceTooLow = errors.New("authority nonce too low")
)

View file

@ -61,6 +61,19 @@ var (
// ErrTxPoolOverflow is returned if the transaction pool is full and can't accept
// another remote transaction.
ErrTxPoolOverflow = errors.New("txpool is full")
// ErrInflightTxLimitReached is returned when the maximum number of in-flight
// transactions is reached for specific accounts.
ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts")
// ErrAuthorityReserved is returned if a transaction has an authorization
// signed by an address which already has in-flight transactions known to the
// pool.
ErrAuthorityReserved = errors.New("authority already reserved")
// ErrFutureReplacePending is returned if a future transaction replaces a pending
// one. Future transactions should only be able to replace other future transactions.
ErrFutureReplacePending = errors.New("future transaction tries to replace pending")
)
var (
@ -572,22 +585,8 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
opts := &txpool.ValidationOptionsWithState{
State: pool.currentState,
FirstNonceGap: nil, // Pool allows arbitrary arrival order, don't invalidate nonce gaps
UsedAndLeftSlots: func(addr common.Address) (int, int) {
var have int
if list := pool.pending[addr]; list != nil {
have += list.Len()
}
if list := pool.queue[addr]; list != nil {
have += list.Len()
}
if pool.currentState.GetCodeHash(addr) != types.EmptyCodeHash || len(pool.all.auths[addr]) != 0 {
// Allow at most one in-flight tx for delegated accounts or those with
// a pending authorization.
return have, max(0, 1-have)
}
return have, math.MaxInt
},
FirstNonceGap: nil, // Pool allows arbitrary arrival order, don't invalidate nonce gaps
UsedAndLeftSlots: nil, // Pool has own mechanism to limit the number of transactions
ExistingExpenditure: func(addr common.Address) *big.Int {
if list := pool.pending[addr]; list != nil {
return list.totalcost.ToBig()
@ -602,22 +601,49 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
}
return nil
},
KnownConflicts: func(from common.Address, auths []common.Address) []common.Address {
var conflicts []common.Address
// Authorities cannot conflict with any pending or queued transactions.
for _, addr := range auths {
if list := pool.pending[addr]; list != nil {
conflicts = append(conflicts, addr)
} else if list := pool.queue[addr]; list != nil {
conflicts = append(conflicts, addr)
}
}
return conflicts
},
}
if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil {
return err
}
return pool.validateAuth(tx)
}
// validateAuth verifies that the transaction complies with code authorization
// restrictions brought by SetCode transaction type.
func (pool *LegacyPool) validateAuth(tx *types.Transaction) error {
from, _ := types.Sender(pool.signer, tx) // validated
// Allow at most one in-flight tx for delegated accounts or those with a
// pending authorization.
if pool.currentState.GetCodeHash(from) != types.EmptyCodeHash || len(pool.all.auths[from]) != 0 {
var (
count int
exists bool
)
pending := pool.pending[from]
if pending != nil {
count += pending.Len()
exists = pending.Contains(tx.Nonce())
}
queue := pool.queue[from]
if queue != nil {
count += queue.Len()
exists = exists || queue.Contains(tx.Nonce())
}
// Replace the existing in-flight transaction for delegated accounts
// are still supported
if count >= 1 && !exists {
return ErrInflightTxLimitReached
}
}
// Authorities cannot conflict with any pending or queued transactions.
if auths := tx.SetCodeAuthorities(); len(auths) > 0 {
for _, auth := range auths {
if pool.pending[auth] != nil || pool.queue[auth] != nil {
return ErrAuthorityReserved
}
}
}
return nil
}
@ -709,7 +735,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) {
pool.priced.Put(dropTx)
}
log.Trace("Discarding future transaction replacing pending tx", "hash", hash)
return false, txpool.ErrFutureReplacePending
return false, ErrFutureReplacePending
}
}

View file

@ -149,6 +149,10 @@ func pricedSetCodeTx(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, ke
})
authList = append(authList, auth)
}
return pricedSetCodeTxWithAuth(nonce, gaslimit, gasFee, tip, key, authList)
}
func pricedSetCodeTxWithAuth(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, authList []types.SetCodeAuthorization) *types.Transaction {
return types.MustSignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.SetCodeTx{
ChainID: uint256.MustFromBig(params.TestChainConfig.ChainID),
Nonce: nonce,
@ -1641,8 +1645,8 @@ func TestUnderpricing(t *testing.T) {
t.Fatalf("failed to add well priced transaction: %v", err)
}
// Ensure that replacing a pending transaction with a future transaction fails
if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != txpool.ErrFutureReplacePending {
t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, txpool.ErrFutureReplacePending)
if err := pool.addRemoteSync(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != ErrFutureReplacePending {
t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, ErrFutureReplacePending)
}
pending, queued = pool.Stats()
if pending != 4 {
@ -2244,12 +2248,12 @@ func TestSetCodeTransactions(t *testing.T) {
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil {
t.Fatalf("%s: failed to add remote transaction: %v", name, err)
}
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err)
}
// Also check gapped transaction.
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrInflightTxLimitReached) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err)
}
// Replace by fee.
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil {
@ -2283,8 +2287,8 @@ func TestSetCodeTransactions(t *testing.T) {
t.Fatalf("%s: failed to add with pending delegatio: %v", name, err)
}
// Also check gapped transaction is rejected.
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, ErrInflightTxLimitReached) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, ErrInflightTxLimitReached, err)
}
},
},
@ -2359,7 +2363,7 @@ func TestSetCodeTransactions(t *testing.T) {
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil {
t.Fatalf("%s: failed to added single pooled for account with pending delegation: %v", name, err)
}
if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), txpool.ErrAccountLimitExceeded; !errors.Is(err, want) {
if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), ErrInflightTxLimitReached; !errors.Is(err, want) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err)
}
},
@ -2372,7 +2376,7 @@ func TestSetCodeTransactions(t *testing.T) {
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil {
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
}
if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), txpool.ErrAuthorityReserved; !errors.Is(err, want) {
if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), ErrAuthorityReserved; !errors.Is(err, want) {
t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err)
}
},
@ -2393,6 +2397,65 @@ func TestSetCodeTransactions(t *testing.T) {
}
}
func TestSetCodeTransactionsReorg(t *testing.T) {
t.Parallel()
// Create the pool to test the status retrievals with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
defer pool.Close()
// Create the test accounts
var (
keyA, _ = crypto.GenerateKey()
addrA = crypto.PubkeyToAddress(keyA.PublicKey)
)
testAddBalance(pool, addrA, big.NewInt(params.Ether))
// Send an authorization for 0x42
var authList []types.SetCodeAuthorization
auth, _ := types.SignSetCode(keyA, types.SetCodeAuthorization{
ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID),
Address: common.Address{0x42},
Nonce: 0,
})
authList = append(authList, auth)
if err := pool.addRemoteSync(pricedSetCodeTxWithAuth(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, authList)); err != nil {
t.Fatalf("failed to add with remote setcode transaction: %v", err)
}
// Simulate the chain moving
blockchain.statedb.SetNonce(addrA, 1, tracing.NonceChangeAuthorization)
blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address))
<-pool.requestReset(nil, nil)
// Set an authorization for 0x00
auth, _ = types.SignSetCode(keyA, types.SetCodeAuthorization{
ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID),
Address: common.Address{},
Nonce: 0,
})
authList = append(authList, auth)
if err := pool.addRemoteSync(pricedSetCodeTxWithAuth(1, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, authList)); err != nil {
t.Fatalf("failed to add with remote setcode transaction: %v", err)
}
// Try to add a transactions in
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); !errors.Is(err, ErrInflightTxLimitReached) {
t.Fatalf("unexpected error %v, expecting %v", err, ErrInflightTxLimitReached)
}
// Simulate the chain moving
blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization)
blockchain.statedb.SetCode(addrA, nil)
<-pool.requestReset(nil, nil)
// Now send two transactions from addrA
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); err != nil {
t.Fatalf("failed to added single transaction: %v", err)
}
if err := pool.addRemoteSync(pricedTransaction(3, 100000, big.NewInt(1000), keyA)); err != nil {
t.Fatalf("failed to added single transaction: %v", err)
}
}
// Benchmarks the speed of validating the contents of the pending queue of the
// transaction pool.
func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }

View file

@ -206,7 +206,7 @@ type ValidationOptionsWithState struct {
// nonce gaps will be ignored and permitted.
FirstNonceGap func(addr common.Address) uint64
// UsedAndLeftSlots is a mandatory callback to retrieve the number of tx slots
// UsedAndLeftSlots is an optional callback to retrieve the number of tx slots
// used and the number still permitted for an account. New transactions will
// be rejected once the number of remaining slots reaches zero.
UsedAndLeftSlots func(addr common.Address) (int, int)
@ -218,11 +218,6 @@ type ValidationOptionsWithState struct {
// ExistingCost is a mandatory callback to retrieve an already pooled
// transaction's cost with the given nonce to check for overdrafts.
ExistingCost func(addr common.Address, nonce uint64) *big.Int
// KnownConflicts is an optional callback which iterates over the list of
// addresses and returns all addresses known to the pool with in-flight
// transactions.
KnownConflicts func(sender common.Address, authorizers []common.Address) []common.Address
}
// ValidateTransactionWithState is a helper method to check whether a transaction
@ -273,15 +268,9 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op
// Transaction takes a new nonce value out of the pool. Ensure it doesn't
// overflow the number of permitted transactions from a single account
// (i.e. max cancellable via out-of-bound transaction).
if used, left := opts.UsedAndLeftSlots(from); left <= 0 {
return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used)
}
// Verify no authorizations will invalidate existing transactions known to
// the pool.
if opts.KnownConflicts != nil {
if conflicts := opts.KnownConflicts(from, tx.SetCodeAuthorities()); len(conflicts) > 0 {
return fmt.Errorf("%w: authorization conflicts with other known tx", ErrAuthorityReserved)
if opts.UsedAndLeftSlots != nil {
if used, left := opts.UsedAndLeftSlots(from); left <= 0 {
return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used)
}
}
}

View file

@ -514,6 +514,5 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
// Now set the inner transaction.
tx.setDecoded(inner, 0)
// TODO: check hash here?
return nil
}

View file

@ -22,39 +22,20 @@ import (
"github.com/holiman/uint256"
)
// ContractRef is a reference to the contract's backing object
type ContractRef interface {
Address() common.Address
}
// AccountRef implements ContractRef.
//
// Account references are used during EVM initialisation and
// its primary use is to fetch addresses. Removing this object
// proves difficult because of the cached jump destinations which
// are fetched from the parent contract (i.e. the caller), which
// is a ContractRef.
type AccountRef common.Address
// Address casts AccountRef to an Address
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
// Contract represents an ethereum contract in the state database. It contains
// the contract code, calling arguments. Contract implements ContractRef
type Contract struct {
// CallerAddress is the result of the caller which initialised this
// contract. However when the "call method" is delegated this value
// needs to be initialised to that of the caller's caller.
CallerAddress common.Address
caller ContractRef
self ContractRef
// caller is the result of the caller which initialised this
// contract. However, when the "call method" is delegated this
// value needs to be initialised to that of the caller's caller.
caller common.Address
address common.Address
jumpdests map[common.Hash]bitvec // Aggregated result of JUMPDEST analysis.
analysis bitvec // Locally cached result of JUMPDEST analysis
Code []byte
CodeHash common.Hash
CodeAddr *common.Address
Input []byte
// is the execution frame represented by this object a contract deployment
@ -66,23 +47,18 @@ type Contract struct {
}
// NewContract returns a new contract environment for the execution of EVM.
func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64) *Contract {
c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object}
if parent, ok := caller.(*Contract); ok {
// Reuse JUMPDEST analysis from parent context if available.
c.jumpdests = parent.jumpdests
} else {
c.jumpdests = make(map[common.Hash]bitvec)
func NewContract(caller common.Address, address common.Address, value *uint256.Int, gas uint64, jumpDests map[common.Hash]bitvec) *Contract {
// Initialize the jump analysis map if it's nil, mostly for tests
if jumpDests == nil {
jumpDests = make(map[common.Hash]bitvec)
}
return &Contract{
caller: caller,
address: address,
jumpdests: jumpDests,
Gas: gas,
value: value,
}
// Gas should be a pointer so it can safely be reduced through the run
// This pointer will be off the state transition
c.Gas = gas
// ensures a value is set
c.value = value
return c
}
func (c *Contract) validJumpdest(dest *uint256.Int) bool {
@ -132,18 +108,6 @@ func (c *Contract) isCode(udest uint64) bool {
return c.analysis.codeSegment(udest)
}
// AsDelegate sets the contract to be a delegate call and returns the current
// contract (for chaining calls)
func (c *Contract) AsDelegate() *Contract {
// NOTE: caller must, at all times be a contract. It should never happen
// that caller is something other than a Contract.
parent := c.caller.(*Contract)
c.CallerAddress = parent.CallerAddress
c.value = parent.value
return c
}
// GetOp returns the n'th element in the contract's byte array
func (c *Contract) GetOp(n uint64) OpCode {
if n < uint64(len(c.Code)) {
@ -158,7 +122,7 @@ func (c *Contract) GetOp(n uint64) OpCode {
// Caller will recursively call caller when the contract is a delegate
// call, including that of caller's caller.
func (c *Contract) Caller() common.Address {
return c.CallerAddress
return c.caller
}
// UseGas attempts the use gas and subtracts it and returns true on success
@ -186,7 +150,7 @@ func (c *Contract) RefundGas(gas uint64, logger *tracing.Hooks, reason tracing.G
// Address returns the contracts address
func (c *Contract) Address() common.Address {
return c.self.Address()
return c.address
}
// Value returns the contract's value (sent to it from it's caller)
@ -194,18 +158,8 @@ func (c *Contract) Value() *uint256.Int {
return c.value
}
// SetCallCode sets the code of the contract and address of the backing data
// object
func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
// SetCallCode sets the code of the contract,
func (c *Contract) SetCallCode(hash common.Hash, code []byte) {
c.Code = code
c.CodeHash = hash
c.CodeAddr = addr
}
// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash.
// In case hash is not provided, the jumpdest analysis will not be saved to the parent context
func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) {
c.Code = codeAndHash.code
c.CodeHash = codeAndHash.hash
c.CodeAddr = addr
}

View file

@ -338,13 +338,9 @@ func opExtCodeCopyEIP4762(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC
}
addr := common.Address(a.Bytes20())
code := interpreter.evm.StateDB.GetCode(addr)
contract := &Contract{
Code: code,
self: AccountRef(addr),
}
paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64())
if !contract.IsSystemCall {
statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false)
if !scope.Contract.IsSystemCall {
statelessGas := interpreter.evm.AccessEvents.CodeChunksRangeGas(addr, copyOffset, nonPaddedCopyLength, uint64(len(code)), false)
if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) {
scope.Contract.Gas = 0
return nil, ErrOutOfGas

View file

@ -91,29 +91,40 @@ type EVM struct {
// Context provides auxiliary blockchain related information
Context BlockContext
TxContext
// StateDB gives access to the underlying state
StateDB StateDB
// Depth is the current call stack
// depth is the current call stack
depth int
// chainConfig contains information about the current chain
chainConfig *params.ChainConfig
// chain rules contains the chain rules for the current epoch
chainRules params.Rules
// virtual machine configuration options used to initialise the
// evm.
// virtual machine configuration options used to initialise the evm
Config Config
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
// global (to this context) ethereum virtual machine used throughout
// the execution of the tx
interpreter *EVMInterpreter
// abort is used to abort the EVM calling operations
abort atomic.Bool
// callGasTemp holds the gas available for the current call. This is needed because the
// available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*.
callGasTemp uint64
// precompiles holds the precompiled contracts for the current epoch
precompiles map[common.Address]PrecompiledContract
// jumpDests is the aggregated result of JUMPDEST analysis made through
// the life cycle of EVM.
jumpDests map[common.Hash]bitvec
}
// NewEVM constructs an EVM instance with the supplied block context, state
@ -127,6 +138,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon
Config: config,
chainConfig: chainConfig,
chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time),
jumpDests: make(map[common.Hash]bitvec),
}
evm.precompiles = activePrecompiledContracts(evm.chainRules)
evm.interpreter = NewEVMInterpreter(evm)
@ -165,18 +177,18 @@ func (evm *EVM) Interpreter() *EVMInterpreter {
return evm.interpreter
}
func isSystemCall(caller ContractRef) bool {
return caller.Address() == params.SystemAddress
func isSystemCall(caller common.Address) bool {
return caller == params.SystemAddress
}
// Call executes the contract associated with the addr with the given input as
// parameters. It also handles any necessary value transfer required and takse
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
// Capture the tracer start/end events in debug mode
if evm.Config.Tracer != nil {
evm.captureBegin(evm.depth, CALL, caller.Address(), addr, input, gas, value.ToBig())
evm.captureBegin(evm.depth, CALL, caller, addr, input, gas, value.ToBig())
defer func(startGas uint64) {
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
@ -186,7 +198,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
return nil, gas, ErrDepth
}
// Fail if we're trying to transfer more than the available balance
if !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
if !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller, value) {
return nil, gas, ErrInsufficientBalance
}
snapshot := evm.StateDB.Snapshot()
@ -209,23 +221,20 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
}
evm.StateDB.CreateAccount(addr)
}
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
evm.Context.Transfer(evm.StateDB, caller, addr, value)
if isPrecompile {
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
code := evm.resolveCode(addr)
if len(code) == 0 {
ret, err = nil, nil // gas is unchanged
} else {
addrCopy := addr
// If the account has no code, we can abort here
// The depth-check is already done, and precompiles handled above
contract := NewContract(caller, AccountRef(addrCopy), value, gas)
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, addr, value, gas, evm.jumpDests)
contract.IsSystemCall = isSystemCall(caller)
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), code)
contract.SetCallCode(evm.resolveCodeHash(addr), code)
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
@ -256,10 +265,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
//
// CallCode differs from Call in the sense that it executes the given address'
// code with the caller as context.
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
// Invoke tracer hooks that signal entering/exiting a call frame
if evm.Config.Tracer != nil {
evm.captureBegin(evm.depth, CALLCODE, caller.Address(), addr, input, gas, value.ToBig())
evm.captureBegin(evm.depth, CALLCODE, caller, addr, input, gas, value.ToBig())
defer func(startGas uint64) {
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
@ -272,7 +281,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// Note although it's noop to transfer X ether to caller itself. But
// if caller doesn't have enough balance, it would be an error to allow
// over-charging itself. So the check here is necessary.
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
if !evm.Context.CanTransfer(evm.StateDB, caller, value) {
return nil, gas, ErrInsufficientBalance
}
var snapshot = evm.StateDB.Snapshot()
@ -281,11 +290,10 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
if p, isPrecompile := evm.precompile(addr); isPrecompile {
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(caller.Address()), value, gas)
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
contract := NewContract(caller, caller, value, gas, evm.jumpDests)
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
@ -295,7 +303,6 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution)
}
gas = 0
}
}
@ -307,14 +314,11 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
//
// DelegateCall differs from CallCode in the sense that it executes the given address'
// code with the caller as context and the caller is set to the caller of the caller.
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
// Invoke tracer hooks that signal entering/exiting a call frame
if evm.Config.Tracer != nil {
// NOTE: caller must, at all times be a contract. It should never happen
// that caller is something other than a Contract.
parent := caller.(*Contract)
// DELEGATECALL inherits value from parent call
evm.captureBegin(evm.depth, DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig())
evm.captureBegin(evm.depth, DELEGATECALL, caller, addr, input, gas, value.ToBig())
defer func(startGas uint64) {
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
@ -329,10 +333,11 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
if p, isPrecompile := evm.precompile(addr); isPrecompile {
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
addrCopy := addr
// Initialise a new contract and make initialise the delegate values
contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate()
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
//
// Note: The value refers to the original value from the parent call.
contract := NewContract(originCaller, caller, value, gas, evm.jumpDests)
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
@ -352,10 +357,10 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// as parameters while disallowing any modifications to the state during the call.
// Opcodes that attempt to perform such modifications will result in exceptions
// instead of performing the modifications.
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
// Invoke tracer hooks that signal entering/exiting a call frame
if evm.Config.Tracer != nil {
evm.captureBegin(evm.depth, STATICCALL, caller.Address(), addr, input, gas, nil)
evm.captureBegin(evm.depth, STATICCALL, caller, addr, input, gas, nil)
defer func(startGas uint64) {
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
@ -380,14 +385,11 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
if p, isPrecompile := evm.precompile(addr); isPrecompile {
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
// At this point, we use a copy of address. If we don't, the go compiler will
// leak the 'contract' to the outer scope, and make allocation for 'contract'
// even if the actual execution ends on RunPrecompiled above.
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas)
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addrCopy), evm.resolveCode(addrCopy))
contract := NewContract(caller, addr, new(uint256.Int), gas, evm.jumpDests)
contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
@ -407,22 +409,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
return ret, gas, err
}
type codeAndHash struct {
code []byte
hash common.Hash
}
func (c *codeAndHash) Hash() common.Hash {
if c.hash == (common.Hash{}) {
c.hash = crypto.Keccak256Hash(c.code)
}
return c.hash
}
// create creates a new contract using code as deployment code.
func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) {
func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *uint256.Int, address common.Address, typ OpCode) (ret []byte, createAddress common.Address, leftOverGas uint64, err error) {
if evm.Config.Tracer != nil {
evm.captureBegin(evm.depth, typ, caller.Address(), address, codeAndHash.code, gas, value.ToBig())
evm.captureBegin(evm.depth, typ, caller, address, code, gas, value.ToBig())
defer func(startGas uint64) {
evm.captureEnd(evm.depth, startGas, leftOverGas, ret, err)
}(gas)
@ -432,14 +422,14 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if evm.depth > int(params.CallCreateDepth) {
return nil, common.Address{}, gas, ErrDepth
}
if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
if !evm.Context.CanTransfer(evm.StateDB, caller, value) {
return nil, common.Address{}, gas, ErrInsufficientBalance
}
nonce := evm.StateDB.GetNonce(caller.Address())
nonce := evm.StateDB.GetNonce(caller)
if nonce+1 < nonce {
return nil, common.Address{}, gas, ErrNonceUintOverflow
}
evm.StateDB.SetNonce(caller.Address(), nonce+1, tracing.NonceChangeContractCreator)
evm.StateDB.SetNonce(caller, nonce+1, tracing.NonceChangeContractCreator)
// Charge the contract creation init gas in verkle mode
if evm.chainRules.IsEIP4762 {
@ -515,15 +505,18 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
gas = gas - statelessGas
}
evm.Context.Transfer(evm.StateDB, caller.Address(), address, value)
evm.Context.Transfer(evm.StateDB, caller, address, value)
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := NewContract(caller, AccountRef(address), value, gas)
contract.SetCodeOptionalHash(&address, codeAndHash)
contract := NewContract(caller, address, value, gas, evm.jumpDests)
// Explicitly set the code to a null hash to prevent caching of jump analysis
// for the initialization code.
contract.SetCallCode(common.Hash{}, code)
contract.IsDeployment = true
ret, err = evm.initNewContract(contract, address, value)
ret, err = evm.initNewContract(contract, address)
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
evm.StateDB.RevertToSnapshot(snapshot)
if err != ErrExecutionReverted {
@ -535,7 +528,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// initNewContract runs a new contract's creation code, performs checks on the
// resulting code that is to be deployed, and consumes necessary gas.
func (evm *EVM) initNewContract(contract *Contract, address common.Address, value *uint256.Int) ([]byte, error) {
func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]byte, error) {
ret, err := evm.interpreter.Run(contract, nil, false)
if err != nil {
return ret, err
@ -567,19 +560,18 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address, valu
}
// Create creates a new contract using code as deployment code.
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE)
func (evm *EVM) Create(caller common.Address, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller, evm.StateDB.GetNonce(caller))
return evm.create(caller, code, gas, value, contractAddr, CREATE)
}
// Create2 creates a new contract using code as deployment code.
//
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
codeAndHash := &codeAndHash{code: code}
contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())
return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
func (evm *EVM) Create2(caller common.Address, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), crypto.Keccak256(code))
return evm.create(caller, code, gas, endowment, contractAddr, CREATE2)
}
// resolveCode returns the code associated with the provided account. After

View file

@ -97,7 +97,7 @@ func TestEIP2200(t *testing.T) {
}
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}})
_, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int))
_, gas, err := evm.Call(common.Address{}, address, nil, tt.gaspool, new(uint256.Int))
if !errors.Is(err, tt.failure) {
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
}
@ -153,7 +153,7 @@ func TestCreateGas(t *testing.T) {
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, config)
var startGas = uint64(testGas)
ret, gas, err := evm.Call(AccountRef(common.Address{}), address, nil, startGas, new(uint256.Int))
ret, gas, err := evm.Call(common.Address{}, address, nil, startGas, new(uint256.Int))
if err != nil {
return false
}

View file

@ -677,7 +677,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation)
res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value)
res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract.Address(), input, gas, &value)
// Push item on the stack based on the returned error. If the ruleset is
// homestead we must check for CodeStoreOutOfGasError (homestead only
// rule) and treat as an error, if the ruleset is frontier we must
@ -718,7 +718,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation2)
// reuse size int for stackvalue
stackvalue := size
res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas,
res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract.Address(), input, gas,
&endowment, &salt)
// Push item on the stack based on the returned error.
if suberr != nil {
@ -755,7 +755,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
if !value.IsZero() {
gas += params.CallStipend
}
ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value)
ret, returnGas, err := interpreter.evm.Call(scope.Contract.Address(), toAddr, args, gas, &value)
if err != nil {
temp.Clear()
@ -789,7 +789,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
gas += params.CallStipend
}
ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, &value)
ret, returnGas, err := interpreter.evm.CallCode(scope.Contract.Address(), toAddr, args, gas, &value)
if err != nil {
temp.Clear()
} else {
@ -818,7 +818,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
// Get arguments from the memory.
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract.Caller(), scope.Contract.Address(), toAddr, args, gas, scope.Contract.value)
if err != nil {
temp.Clear()
} else {
@ -847,7 +847,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
// Get arguments from the memory.
args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract.Address(), toAddr, args, gas)
if err != nil {
temp.Clear()
} else {

View file

@ -49,14 +49,6 @@ var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffff
var commonParams []*twoOperandParams
var twoOpMethods map[string]executionFunc
type contractRef struct {
addr common.Address
}
func (c contractRef) Address() common.Address {
return c.addr
}
func init() {
// Params is a list of common edgecases that should be used for some common tests
params := []string{
@ -575,8 +567,7 @@ func TestOpTstore(t *testing.T) {
mem = NewMemory()
caller = common.Address{}
to = common.Address{1}
contractRef = contractRef{caller}
contract = NewContract(contractRef, AccountRef(to), new(uint256.Int), 0)
contract = NewContract(caller, to, new(uint256.Int), 0, nil)
scopeContext = ScopeContext{mem, stack, contract}
value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700")
)

View file

@ -17,8 +17,6 @@
package vm
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/stateless"
@ -104,16 +102,3 @@ type StateDB interface {
// Finalise must be invoked at the end of a transaction
Finalise(bool)
}
// CallContext provides a basic interface for the EVM calling conventions. The EVM
// depends on this context being implemented for doing subcalls and initialising new EVM contracts.
type CallContext interface {
// Call calls another contract.
Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
// CallCode takes another contracts code and execute within our own context
CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error)
// DelegateCall is same as CallCode except sender and value is propagated from parent to child scope
DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error)
// Create creates a new contract
Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)
}

View file

@ -53,7 +53,7 @@ func TestLoopInterrupt(t *testing.T) {
timeout := make(chan bool)
go func(evm *EVM) {
_, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(uint256.Int))
_, _, err := evm.Call(common.Address{}, address, nil, math.MaxUint64, new(uint256.Int))
errChannel <- err
}(evm)

View file

@ -128,7 +128,6 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
var (
address = common.BytesToAddress([]byte("contract"))
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
)
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
@ -143,7 +142,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
cfg.State.SetCode(address, code)
// Call the code with the given configuration.
ret, leftOverGas, err := vmenv.Call(
sender,
cfg.Origin,
common.BytesToAddress([]byte("contract")),
input,
cfg.GasLimit,
@ -166,9 +165,8 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
}
var (
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
vmenv = NewEnv(cfg)
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
)
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
@ -179,7 +177,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, nil, vm.ActivePrecompiles(rules), nil)
// Call the code with the given configuration.
code, address, leftOverGas, err := vmenv.Create(
sender,
cfg.Origin,
input,
cfg.GasLimit,
uint256.MustFromBig(cfg.Value),
@ -200,7 +198,6 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
var (
vmenv = NewEnv(cfg)
sender = vm.AccountRef(cfg.Origin)
statedb = cfg.State
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
)
@ -214,7 +211,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er
// Call the code with the given configuration.
ret, leftOverGas, err := vmenv.Call(
sender,
cfg.Origin,
address,
input,
cfg.GasLimit,

View file

@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/asm"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
@ -508,21 +507,9 @@ func TestEip2929Cases(t *testing.T) {
t.Skip("Test only useful for generating documentation")
id := 1
prettyPrint := func(comment string, code []byte) {
instrs := make([]string, 0)
it := asm.NewInstructionIterator(code)
for it.Next() {
if it.Arg() != nil && 0 < len(it.Arg()) {
instrs = append(instrs, fmt.Sprintf("%v %#x", it.Op(), it.Arg()))
} else {
instrs = append(instrs, fmt.Sprintf("%v", it.Op()))
}
}
ops := strings.Join(instrs, ", ")
fmt.Printf("### Case %d\n\n", id)
id++
fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\nOperations: \n```\n%v\n```\n\n",
comment,
code, ops)
fmt.Printf("%v\n\nBytecode: \n```\n%#x\n```\n", comment, code)
Execute(code, nil, &Config{
EVMConfig: vm.Config{
Tracer: logger.NewMarkdownLogger(nil, os.Stdout).Hooks(),

View file

@ -184,6 +184,9 @@ func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
}
// FromECDSAPub converts a secp256k1 public key to bytes.
// Note: it does not use the curve from pub, instead it always
// encodes using secp256k1.
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil

View file

@ -181,7 +181,7 @@ func TestLoadECDSA(t *testing.T) {
}
for _, test := range tests {
f, err := os.CreateTemp("", "loadecdsa_test.*.txt")
f, err := os.CreateTemp(t.TempDir(), "loadecdsa_test.*.txt")
if err != nil {
t.Fatal(err)
}
@ -202,7 +202,7 @@ func TestLoadECDSA(t *testing.T) {
}
func TestSaveECDSA(t *testing.T) {
f, err := os.CreateTemp("", "saveecdsa_test.*.txt")
f, err := os.CreateTemp(t.TempDir(), "saveecdsa_test.*.txt")
if err != nil {
t.Fatal(err)
}

View file

@ -33,11 +33,10 @@ var (
)
func TestSignify(t *testing.T) {
tmpFile, err := os.CreateTemp("", "")
tmpFile, err := os.CreateTemp(t.TempDir(), "")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
data := make([]byte, 1024)
@ -52,7 +51,6 @@ func TestSignify(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name() + ".sig")
// Verify the signature using a golang library
sig, err := minisign.NewSignatureFromFile(tmpFile.Name() + ".sig")
@ -75,11 +73,10 @@ func TestSignify(t *testing.T) {
}
func TestSignifyTrustedCommentTooManyLines(t *testing.T) {
tmpFile, err := os.CreateTemp("", "")
tmpFile, err := os.CreateTemp(t.TempDir(), "")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
data := make([]byte, 1024)
@ -94,15 +91,13 @@ func TestSignifyTrustedCommentTooManyLines(t *testing.T) {
if err == nil || err.Error() == "" {
t.Fatalf("should have errored on a multi-line trusted comment, got %v", err)
}
defer os.Remove(tmpFile.Name() + ".sig")
}
func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) {
tmpFile, err := os.CreateTemp("", "")
tmpFile, err := os.CreateTemp(t.TempDir(), "")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
data := make([]byte, 1024)
@ -117,15 +112,13 @@ func TestSignifyTrustedCommentTooManyLinesLF(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name() + ".sig")
}
func TestSignifyTrustedCommentEmpty(t *testing.T) {
tmpFile, err := os.CreateTemp("", "")
tmpFile, err := os.CreateTemp(t.TempDir(), "")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name())
defer tmpFile.Close()
data := make([]byte, 1024)
@ -140,5 +133,4 @@ func TestSignifyTrustedCommentEmpty(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name() + ".sig")
}

View file

@ -368,7 +368,9 @@ func (s *Ethereum) Protocols() []p2p.Protocol {
// Start implements node.Lifecycle, starting all internal goroutines needed by the
// Ethereum protocol implementation.
func (s *Ethereum) Start() error {
s.setupDiscovery()
if err := s.setupDiscovery(); err != nil {
return err
}
// Start the bloom bits servicing goroutines
s.startBloomHandlers(params.BloomBitsBlocks)

View file

@ -33,6 +33,8 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params/forks"
"github.com/ethereum/go-ethereum/rpc"
)
@ -95,6 +97,16 @@ type SimulatedBeacon struct {
lastBlockTime uint64
}
func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersion {
switch config.LatestFork(time) {
case forks.Prague, forks.Cancun:
return engine.PayloadV3
case forks.Paris, forks.Shanghai:
return engine.PayloadV2
}
panic("invalid fork, simulated beacon needs to be started post-merge")
}
// NewSimulatedBeacon constructs a new simulated beacon chain.
func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
block := eth.BlockChain().CurrentBlock()
@ -107,7 +119,8 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err
// if genesis block, send forkchoiceUpdated to trigger transition to PoS
if block.Number.Sign() == 0 {
if _, err := engineAPI.ForkchoiceUpdatedV3(current, nil); err != nil {
version := payloadVersion(eth.BlockChain().Config(), block.Time)
if _, err := engineAPI.forkchoiceUpdated(current, nil, version, false); err != nil {
return nil, err
}
}
@ -171,10 +184,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
return fmt.Errorf("failed to sync txpool: %w", err)
}
payloadVersion := engine.PayloadV3
if header := c.eth.BlockChain().CurrentBlock(); !c.eth.BlockChain().Config().IsCancun(header.Number, timestamp) {
payloadVersion = engine.PayloadV2
}
version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
var random [32]byte
rand.Read(random[:])
@ -184,7 +194,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
Withdrawals: withdrawals,
Random: random,
BeaconRoot: &common.Hash{},
}, payloadVersion, false)
}, version, false)
if err != nil {
return err
}
@ -209,27 +219,28 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
}
}
// Independently calculate the blob hashes from sidecars.
blobHashes := make([]common.Hash, 0)
if envelope.BlobsBundle != nil {
hasher := sha256.New()
for _, commit := range envelope.BlobsBundle.Commitments {
var c kzg4844.Commitment
if len(commit) != len(c) {
return errors.New("invalid commitment length")
var (
blobHashes []common.Hash
beaconRoot *common.Hash
requests [][]byte
)
// Compute post-shanghai fields
if version > engine.PayloadV2 {
// Independently calculate the blob hashes from sidecars.
blobHashes = make([]common.Hash, 0)
if envelope.BlobsBundle != nil {
hasher := sha256.New()
for _, commit := range envelope.BlobsBundle.Commitments {
var c kzg4844.Commitment
if len(commit) != len(c) {
return errors.New("invalid commitment length")
}
copy(c[:], commit)
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
}
copy(c[:], commit)
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
}
}
beaconRoot := &common.Hash{}
requests := envelope.Requests
if payloadVersion == engine.PayloadV2 {
blobHashes = nil
beaconRoot = nil
requests = nil
beaconRoot = &common.Hash{}
requests = envelope.Requests
}
// Mark the payload as canon
@ -240,7 +251,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
c.setCurrentState(payload.BlockHash, finalizedHash)
// Mark the block containing the payload as canonical
if _, err = c.engineAPI.ForkchoiceUpdatedV3(c.curForkchoiceState, nil); err != nil {
if _, err = c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, nil, version, false); err != nil {
return err
}
c.lastBlockTime = payload.Timestamp

View file

@ -42,6 +42,7 @@ func StartENRUpdater(chain *core.BlockChain, ln *enode.LocalNode) {
var newHead = make(chan core.ChainHeadEvent, 10)
sub := chain.SubscribeChainHeadEvent(newHead)
ln.Set(currentENREntry(chain))
go func() {
defer sub.Unsubscribe()
for {
@ -71,7 +72,7 @@ func NewNodeFilter(chain *core.BlockChain) func(*enode.Node) bool {
filter := forkid.NewFilter(chain)
return func(n *enode.Node) bool {
var entry enrEntry
if err := n.Load(entry); err != nil {
if err := n.Load(&entry); err != nil {
return false
}
err := filter(entry.ForkID)

View file

@ -65,11 +65,8 @@ type callTrace struct {
// callTracerTest defines a single test to check the call tracer against.
type callTracerTest struct {
Genesis *core.Genesis `json:"genesis"`
Context *callContext `json:"context"`
Input string `json:"input"`
TracerConfig json.RawMessage `json:"tracerConfig"`
Result *callTrace `json:"result"`
tracerTestEnv
Result *callTrace `json:"result"`
}
// Iterates over all the input-output datasets in the tracer test harness and

View file

@ -77,11 +77,8 @@ type flatCallTraceResult struct {
// flatCallTracerTest defines a single test to check the call tracer against.
type flatCallTracerTest struct {
Genesis *core.Genesis `json:"genesis"`
Context *callContext `json:"context"`
Input string `json:"input"`
TracerConfig json.RawMessage `json:"tracerConfig"`
Result []flatCallTrace `json:"result"`
tracerTestEnv
Result []flatCallTrace `json:"result"`
}
func flatCallTracerTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error {

View file

@ -31,6 +31,9 @@ var makeTest = function(tx, traceConfig) {
delete genesis.transactions;
delete genesis.transactionsRoot;
delete genesis.uncles;
delete genesis.withdrawals;
delete genesis.withdrawalsRoot;
delete genesis.baseFeePerGas;
genesis.gasLimit = genesis.gasLimit.toString();
genesis.number = genesis.number.toString();
@ -60,11 +63,15 @@ var makeTest = function(tx, traceConfig) {
context.baseFeePerGas = block.baseFeePerGas.toString();
}
console.log(JSON.stringify({
var data = {
genesis: genesis,
context: context,
input: eth.getRawTransaction(tx),
result: result,
tracerConfig: traceConfig.tracerConfig,
}, null, 2));
input: eth.getRawTransaction(tx),
result: result,
};
if (traceConfig && traceConfig.tracerConfig) {
data.tracerConfig = traceConfig.tracerConfig;
}
console.log(JSON.stringify(data, null, 2));
}

View file

@ -43,28 +43,25 @@ type account struct {
Storage map[common.Hash]common.Hash `json:"storage"`
}
// testcase defines a single test to check the stateDiff tracer against.
type testcase struct {
Genesis *core.Genesis `json:"genesis"`
Context *callContext `json:"context"`
Input string `json:"input"`
TracerConfig json.RawMessage `json:"tracerConfig"`
Result interface{} `json:"result"`
// prestateTracerTest defines a single test to check the stateDiff tracer against.
type prestateTracerTest struct {
tracerTestEnv
Result interface{} `json:"result"`
}
func TestPrestateTracerLegacy(t *testing.T) {
testPrestateDiffTracer("prestateTracerLegacy", "prestate_tracer_legacy", t)
testPrestateTracer("prestateTracerLegacy", "prestate_tracer_legacy", t)
}
func TestPrestateTracer(t *testing.T) {
testPrestateDiffTracer("prestateTracer", "prestate_tracer", t)
testPrestateTracer("prestateTracer", "prestate_tracer", t)
}
func TestPrestateWithDiffModeTracer(t *testing.T) {
testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t)
testPrestateTracer("prestateTracer", "prestate_tracer_with_diff_mode", t)
}
func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
func testPrestateTracer(tracerName string, dirPath string, t *testing.T) {
files, err := os.ReadDir(filepath.Join("testdata", dirPath))
if err != nil {
t.Fatalf("failed to retrieve tracer test suite: %v", err)
@ -77,7 +74,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
t.Parallel()
var (
test = new(testcase)
test = new(prestateTracerTest)
tx = new(types.Transaction)
)
// Call tracer test found, read if from disk

View file

@ -14,8 +14,6 @@
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a",
"timestamp": "1709626771",
"withdrawals": [],
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"alloc": {
"0x0000000000000000000000000000000000000000": {
"balance": "0x272e0528"

View file

@ -14,8 +14,6 @@
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x577f42ab21ccfd946511c57869ace0bdf7c217c36f02b7cd3459df0ed1cffc1a",
"timestamp": "1709626771",
"withdrawals": [],
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"alloc": {
"0x0000000000000000000000000000000000000000": {
"balance": "0x272e0528"

View file

@ -11,8 +11,6 @@
"number": "1",
"stateRoot": "0xd2ebe0a7f3572ffe3e5b4c78147376d3fca767f236e4dd23f9151acfec7cb0d1",
"timestamp": "1699617692",
"withdrawals": [],
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"alloc": {
"0x0000000000000000000000000000000000000000": {
"balance": "0x5208"

View file

@ -17,6 +17,7 @@
package tracetest
import (
"encoding/json"
"math/big"
"strings"
"unicode"
@ -42,7 +43,8 @@ func camel(str string) string {
return strings.Join(pieces, "")
}
type callContext struct {
// traceContext defines a context used to construct the block context
type traceContext struct {
Number math.HexOrDecimal64 `json:"number"`
Difficulty *math.HexOrDecimal256 `json:"difficulty"`
Time math.HexOrDecimal64 `json:"timestamp"`
@ -51,7 +53,7 @@ type callContext struct {
BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
}
func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext {
func (c *traceContext) toBlockContext(genesis *core.Genesis) vm.BlockContext {
context := vm.BlockContext{
CanTransfer: core.CanTransfer,
Transfer: core.Transfer,
@ -77,3 +79,11 @@ func (c *callContext) toBlockContext(genesis *core.Genesis) vm.BlockContext {
}
return context
}
// tracerTestEnv defines a tracer test required fields
type tracerTestEnv struct {
Genesis *core.Genesis `json:"genesis"`
Context *traceContext `json:"context"`
Input string `json:"input"`
TracerConfig json.RawMessage `json:"tracerConfig"`
}

View file

@ -33,19 +33,6 @@ import (
"github.com/holiman/uint256"
)
type account struct{}
func (account) SubBalance(amount *big.Int) {}
func (account) AddBalance(amount *big.Int) {}
func (account) SetAddress(common.Address) {}
func (account) Value() *big.Int { return nil }
func (account) SetBalance(*uint256.Int) {}
func (account) SetNonce(uint64) {}
func (account) Balance() *uint256.Int { return nil }
func (account) Address() common.Address { return common.Address{} }
func (account) SetCode(common.Hash, []byte) {}
func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
type dummyStatedb struct {
state.StateDB
}
@ -68,7 +55,7 @@ func runTrace(tracer *tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainCo
gasLimit uint64 = 31000
startGas uint64 = 10000
value = uint256.NewInt(0)
contract = vm.NewContract(account{}, account{}, value, startGas)
contract = vm.NewContract(common.Address{}, common.Address{}, value, startGas, nil)
)
evm.SetTxContext(vmctx.txCtx)
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
@ -190,7 +177,7 @@ func TestHaltBetweenSteps(t *testing.T) {
t.Fatal(err)
}
scope := &vm.ScopeContext{
Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0),
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), 0, nil),
}
evm := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, chainConfig, vm.Config{Tracer: tracer.Hooks})
evm.SetTxContext(vm.TxContext{GasPrice: big.NewInt(1)})
@ -288,7 +275,7 @@ func TestEnterExit(t *testing.T) {
t.Fatal(err)
}
scope := &vm.ScopeContext{
Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0),
Contract: vm.NewContract(common.Address{}, common.Address{}, uint256.NewInt(0), 0, nil),
}
tracer.OnEnter(1, byte(vm.CALL), scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int))
tracer.OnExit(1, []byte{}, 400, nil, false)

View file

@ -29,22 +29,6 @@ import (
"github.com/holiman/uint256"
)
type dummyContractRef struct {
calledForEach bool
}
func (dummyContractRef) Address() common.Address { return common.Address{} }
func (dummyContractRef) Value() *big.Int { return new(big.Int) }
func (dummyContractRef) SetCode(common.Hash, []byte) {}
func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
d.calledForEach = true
}
func (d *dummyContractRef) SubBalance(amount *big.Int) {}
func (d *dummyContractRef) AddBalance(amount *big.Int) {}
func (d *dummyContractRef) SetBalance(*big.Int) {}
func (d *dummyContractRef) SetNonce(uint64) {}
func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) }
type dummyStatedb struct {
state.StateDB
}
@ -59,7 +43,7 @@ func TestStoreCapture(t *testing.T) {
var (
logger = NewStructLogger(nil)
evm = vm.NewEVM(vm.BlockContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger.Hooks()})
contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 100000)
contract = vm.NewContract(common.Address{}, common.Address{}, new(uint256.Int), 100000, nil)
)
contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
var index common.Hash

View file

@ -85,11 +85,23 @@ func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo
return ec.getBlock(ctx, "eth_getBlockByHash", hash, true)
}
// BlockByNumber returns a block from the current canonical chain. If number is nil, the
// latest known block is returned.
// BlockByNumber returns a block from the current canonical chain.
// If `number` is nil, the latest known block is returned.
//
// Note that loading full blocks requires two requests. Use HeaderByNumber
// if you don't need all transactions or uncle headers.
// Use `HeaderByNumber` if you don't need full transaction data or uncle headers.
//
// Supported special block number tags:
// - `earliest` : The genesis (earliest) block
// - `latest` : The most recently included block
// - `safe` : The latest safe head block
// - `finalized` : The latest finalized block
// - `pending` : The pending block
//
// Example usage:
//
// ```go
// BlockByNumber(context.Background(), big.NewInt(int64(rpc.LatestBlockNumber)))
// ```
func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true)
}
@ -210,8 +222,21 @@ func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He
return head, err
}
// HeaderByNumber returns a block header from the current canonical chain. If number is
// nil, the latest known header is returned.
// HeaderByNumber returns a block header from the current canonical chain.
// If `number` is nil, the latest known block header is returned.
//
// Supported special block number tags:
// - `earliest` : The genesis (earliest) block
// - `latest` : The most recently included block
// - `safe` : The latest safe head block
// - `finalized` : The latest finalized block
// - `pending` : The pending block
//
// Example usage:
//
// ```go
// HeaderByNumber(context.Background(), big.NewInt(int64(rpc.LatestBlockNumber)))
// ```
func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
var head *types.Header
err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", toBlockNumArg(number), false)

View file

@ -25,6 +25,8 @@ import (
"testing"
"time"
"go.uber.org/goleak"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/holiman/uint256"
@ -350,3 +352,20 @@ func TestAdjustTimeAfterFork(t *testing.T) {
t.Errorf("failed to build block on fork")
}
}
func createAndCloseSimBackend() {
genesisData := types.GenesisAlloc{}
simulatedBackend := NewBackend(genesisData)
defer simulatedBackend.Close()
}
// TestCheckSimBackendGoroutineLeak checks whether creation of a simulated backend leaks go-routines. Any long-lived go-routines
// spawned by global variables are not considered leaked.
func TestCheckSimBackendGoroutineLeak(t *testing.T) {
createAndCloseSimBackend()
ignoreCur := goleak.IgnoreCurrent()
// ignore this leveldb function: this go-routine is guaranteed to be terminated 1 second after closing db handle
ignoreLdb := goleak.IgnoreAnyFunction("github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain")
createAndCloseSimBackend()
goleak.VerifyNone(t, ignoreCur, ignoreLdb)
}

19
go.mod
View file

@ -1,6 +1,6 @@
module github.com/ethereum/go-ethereum
go 1.22.0
go 1.23.0
require (
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
@ -11,7 +11,7 @@ require (
github.com/aws/aws-sdk-go-v2/credentials v1.13.43
github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2
github.com/cespare/cp v0.1.0
github.com/cloudflare/cloudflare-go v0.79.0
github.com/cloudflare/cloudflare-go v0.114.0
github.com/cockroachdb/pebble v1.1.2
github.com/consensys/gnark-crypto v0.14.0
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a
@ -59,17 +59,18 @@ require (
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
github.com/status-im/keycard-go v0.2.0
github.com/streamingfast/firehose-ethereum/types v0.0.0-20250219193809-31f4c76a8a5d
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/supranational/blst v0.3.14
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/urfave/cli/v2 v2.25.7
github.com/urfave/cli/v2 v2.27.5
go.uber.org/automaxprocs v1.5.2
go.uber.org/goleak v1.3.0
golang.org/x/crypto v0.32.0
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/sync v0.10.0
golang.org/x/sys v0.29.0
golang.org/x/text v0.21.0
golang.org/x/time v0.5.0
golang.org/x/time v0.9.0
golang.org/x/tools v0.29.0
google.golang.org/protobuf v1.34.2
gopkg.in/natefinch/lumberjack.v2 v2.2.1
@ -99,20 +100,18 @@ require (
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/consensys/bavard v0.1.22 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/deepmap/oapi-codegen v1.6.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kilic/bls12-381 v0.1.0 // indirect
@ -143,7 +142,7 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.34.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

37
go.sum
View file

@ -107,8 +107,8 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.79.0 h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M=
github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc=
github.com/cloudflare/cloudflare-go v0.114.0 h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA=
github.com/cloudflare/cloudflare-go v0.114.0/go.mod h1:O7fYfFfA6wKqKFn2QIR9lhj7FDw6VQCGOY6hd2TBtd0=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
@ -128,8 +128,8 @@ github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI
github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E=
github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM=
github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=
@ -206,8 +206,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -292,13 +292,6 @@ github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY4
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
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 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4=
@ -508,8 +501,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo=
github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
@ -518,13 +511,13 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -537,6 +530,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -740,8 +735,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=

View file

@ -37,7 +37,7 @@ func TestEra1Builder(t *testing.T) {
t.Parallel()
// Get temp directory.
f, err := os.CreateTemp("", "era1-test")
f, err := os.CreateTemp(t.TempDir(), "era1-test")
if err != nil {
t.Fatalf("error creating temp file: %v", err)
}
@ -78,6 +78,7 @@ func TestEra1Builder(t *testing.T) {
if err != nil {
t.Fatalf("failed to open era: %v", err)
}
defer e.Close()
it, err := NewRawIterator(e)
if err != nil {
t.Fatalf("failed to make iterator: %s", err)

View file

@ -775,7 +775,7 @@ func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockN
//
// Note, this function doesn't make any changes in the state/blockchain and is
// useful to execute and retrieve values.
func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]*simBlockResult, error) {
if len(opts.BlockStateCalls) == 0 {
return nil, &invalidParamsError{message: "empty input"}
} else if len(opts.BlockStateCalls) > maxSimulateBlocks {

View file

@ -24,6 +24,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"math/big"
"os"
"path/filepath"
@ -2309,6 +2310,101 @@ func TestSimulateV1(t *testing.T) {
}
}
func TestSimulateV1ChainLinkage(t *testing.T) {
var (
acc = newTestAccount()
sender = acc.addr
contractAddr = common.Address{0xaa, 0xaa}
recipient = common.Address{0xbb, 0xbb}
gspec = &core.Genesis{
Config: params.MergedTestChainConfig,
Alloc: types.GenesisAlloc{
sender: {Balance: big.NewInt(params.Ether)},
contractAddr: {Code: common.Hex2Bytes("5f35405f8114600f575f5260205ff35b5f80fd")},
},
}
signer = types.LatestSigner(params.MergedTestChainConfig)
)
backend := newTestBackend(t, 1, gspec, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
tx := types.MustSignNewTx(acc.key, signer, &types.LegacyTx{
Nonce: uint64(i),
GasPrice: b.BaseFee(),
Gas: params.TxGas,
To: &recipient,
Value: big.NewInt(500),
})
b.AddTx(tx)
})
ctx := context.Background()
stateDB, baseHeader, err := backend.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber))
if err != nil {
t.Fatalf("failed to get state and header: %v", err)
}
sim := &simulator{
b: backend,
state: stateDB,
base: baseHeader,
chainConfig: backend.ChainConfig(),
gp: new(core.GasPool).AddGas(math.MaxUint64),
traceTransfers: false,
validate: false,
fullTx: false,
}
var (
call1 = TransactionArgs{
From: &sender,
To: &recipient,
Value: (*hexutil.Big)(big.NewInt(1000)),
}
call2 = TransactionArgs{
From: &sender,
To: &recipient,
Value: (*hexutil.Big)(big.NewInt(2000)),
}
call3a = TransactionArgs{
From: &sender,
To: &contractAddr,
Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 1)),
Gas: newUint64(1000000),
}
call3b = TransactionArgs{
From: &sender,
To: &contractAddr,
Input: uint256ToBytes(uint256.NewInt(baseHeader.Number.Uint64() + 2)),
Gas: newUint64(1000000),
}
blocks = []simBlock{
{Calls: []TransactionArgs{call1}},
{Calls: []TransactionArgs{call2}},
{Calls: []TransactionArgs{call3a, call3b}},
}
)
results, err := sim.execute(ctx, blocks)
if err != nil {
t.Fatalf("simulation execution failed: %v", err)
}
require.Equal(t, 3, len(results), "expected 3 simulated blocks")
// Check linkages of simulated blocks:
// Verify that block2's parent hash equals block1's hash.
block1 := results[0].Block
block2 := results[1].Block
block3 := results[2].Block
require.Equal(t, block1.ParentHash(), baseHeader.Hash(), "parent hash of block1 should equal hash of base block")
require.Equal(t, block1.Hash(), block2.Header().ParentHash, "parent hash of block2 should equal hash of block1")
require.Equal(t, block2.Hash(), block3.Header().ParentHash, "parent hash of block3 should equal hash of block2")
// In block3, two calls were executed to our contract.
// The first call in block3 should return the blockhash for block1 (i.e. block1.Hash()),
// whereas the second call should return the blockhash for block2 (i.e. block2.Hash()).
require.Equal(t, block1.Hash().Bytes(), []byte(results[2].Calls[0].ReturnValue), "returned blockhash for block1 does not match")
require.Equal(t, block2.Hash().Bytes(), []byte(results[2].Calls[1].ReturnValue), "returned blockhash for block2 does not match")
}
func TestSignTransaction(t *testing.T) {
t.Parallel()
// Initialize test accounts

View file

@ -73,6 +73,20 @@ func (r *simCallResult) MarshalJSON() ([]byte, error) {
return json.Marshal((*callResultAlias)(r))
}
// simBlockResult is the result of a simulated block.
type simBlockResult struct {
fullTx bool
chainConfig *params.ChainConfig
Block *types.Block
Calls []simCallResult
}
func (r *simBlockResult) MarshalJSON() ([]byte, error) {
blockData := RPCMarshalBlock(r.Block, true, r.fullTx, r.chainConfig)
blockData["calls"] = r.Calls
return json.Marshal(blockData)
}
// simOpts are the inputs to eth_simulateV1.
type simOpts struct {
BlockStateCalls []simBlock
@ -95,7 +109,7 @@ type simulator struct {
}
// execute runs the simulation of a series of blocks.
func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[string]interface{}, error) {
func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]*simBlockResult, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
@ -123,7 +137,7 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[str
return nil, err
}
var (
results = make([]map[string]interface{}, len(blocks))
results = make([]*simBlockResult, len(blocks))
parent = sim.base
)
for bi, block := range blocks {
@ -131,11 +145,9 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[str
if err != nil {
return nil, err
}
enc := RPCMarshalBlock(result, true, sim.fullTx, sim.chainConfig)
enc["calls"] = callResults
results[bi] = enc
parent = headers[bi]
headers[bi] = result.Header()
results[bi] = &simBlockResult{fullTx: sim.fullTx, chainConfig: sim.chainConfig, Block: result, Calls: callResults}
parent = result.Header()
}
return results, nil
}
@ -194,6 +206,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
if precompiles != nil {
evm.SetPrecompiles(precompiles)
}
if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) {
core.ProcessParentBlockHash(header.ParentHash, evm)
}
var allLogs []*types.Log
for i, call := range block.Calls {
if err := ctx.Err(); err != nil {
return nil, nil, err
@ -234,9 +250,23 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
}
} else {
callRes.Status = hexutil.Uint64(types.ReceiptStatusSuccessful)
allLogs = append(allLogs, callRes.Logs...)
}
callResults[i] = callRes
}
var requests [][]byte
// Process EIP-7685 requests
if sim.chainConfig.IsPrague(header.Number, header.Time) {
requests = [][]byte{}
// EIP-6110
if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil {
return nil, nil, err
}
// EIP-7002
core.ProcessWithdrawalQueue(&requests, evm)
// EIP-7251
core.ProcessConsolidationQueue(&requests, evm)
}
header.Root = sim.state.IntermediateRoot(true)
header.GasUsed = gasUsed
if sim.chainConfig.IsCancun(header.Number, header.Time) {
@ -246,6 +276,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
if sim.chainConfig.IsShanghai(header.Number, header.Time) {
withdrawals = make([]*types.Withdrawal, 0)
}
if requests != nil {
reqHash := types.CalcRequestsHash(requests)
header.RequestsHash = &reqHash
}
b := types.NewBlock(header, &types.Body{Transactions: txes, Withdrawals: withdrawals}, receipts, trie.NewStackTrie(nil))
repairLogs(callResults, b.Hash())
return b, callResults, nil

View file

@ -53,13 +53,12 @@ func TestDatadirCreation(t *testing.T) {
t.Fatalf("freshly created datadir not accessible: %v", err)
}
// Verify that an impossible datadir fails creation
file, err := os.CreateTemp("", "")
file, err := os.CreateTemp(t.TempDir(), "")
if err != nil {
t.Fatalf("failed to create temporary file: %v", err)
}
defer func() {
file.Close()
os.Remove(file.Name())
}()
dir = filepath.Join(file.Name(), "invalid/path")

View file

@ -160,14 +160,6 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG1Add fuzz_g1_add\
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzCrossG1Mul fuzz_cross_g1_mul\
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG1Mul fuzz_g1_mul\
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG1MultiExp fuzz_g1_multiexp \
$repo/tests/fuzzers/bls12381/bls12381_test.go
@ -176,14 +168,6 @@ compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG2Add fuzz_g2_add \
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzCrossG2Mul fuzz_cross_g2_mul\
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG2Mul fuzz_g2_mul\
$repo/tests/fuzzers/bls12381/bls12381_test.go
compile_fuzzer github.com/ethereum/go-ethereum/tests/fuzzers/bls12381 \
FuzzG2MultiExp fuzz_g2_multiexp \
$repo/tests/fuzzers/bls12381/bls12381_test.go

View file

@ -263,7 +263,7 @@ func (it *randomIterator) Next() bool {
func (it *randomIterator) addTree(url string) error {
le, err := parseLink(url)
if err != nil {
return fmt.Errorf("invalid enrtree URL: %v", err)
return fmt.Errorf("invalid DNS discovery URL %q: %v", url, err)
}
it.lc.addLink("", le.str)
return nil

View file

@ -18,17 +18,8 @@ package nat
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNatStun(t *testing.T) {
nat, err := newSTUN("")
assert.NoError(t, err)
_, err = nat.ExternalIP()
assert.NoError(t, err)
}
func TestUnreachedNatServer(t *testing.T) {
stun := &stun{
serverList: []string{"198.51.100.2:1234", "198.51.100.5"},

View file

@ -319,10 +319,17 @@ var (
Max: 9,
UpdateFraction: 5007716,
}
// DefaultOsakaBlobConfig is the default blob configuration for the Osaka fork.
DefaultOsakaBlobConfig = &BlobConfig{
Target: 6,
Max: 9,
UpdateFraction: 5007716,
}
// DefaultBlobSchedule is the latest configured blob schedule for test chains.
DefaultBlobSchedule = &BlobScheduleConfig{
Cancun: DefaultCancunBlobConfig,
Prague: DefaultPragueBlobConfig,
Osaka: DefaultOsakaBlobConfig,
}
)
@ -503,6 +510,7 @@ type BlobConfig struct {
type BlobScheduleConfig struct {
Cancun *BlobConfig `json:"cancun,omitempty"`
Prague *BlobConfig `json:"prague,omitempty"`
Osaka *BlobConfig `json:"osaka,omitempty"`
Verkle *BlobConfig `json:"verkle,omitempty"`
}
@ -734,6 +742,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
}{
{name: "cancun", timestamp: c.CancunTime, config: bsc.Cancun},
{name: "prague", timestamp: c.PragueTime, config: bsc.Prague},
{name: "osaka", timestamp: c.OsakaTime, config: bsc.Osaka},
} {
if cur.config != nil {
if err := cur.config.validate(); err != nil {

View file

@ -501,7 +501,16 @@ func (typedData *TypedData) encodeArrayValue(encValue interface{}, encType strin
for _, item := range arrayValue {
if reflect.TypeOf(item).Kind() == reflect.Slice ||
reflect.TypeOf(item).Kind() == reflect.Array {
encodedData, err := typedData.encodeArrayValue(item, parsedType, depth+1)
var (
encodedData hexutil.Bytes
err error
)
if reflect.TypeOf(item).Elem().Kind() == reflect.Uint8 {
// the item type is bytes. encode the bytes array directly instead of recursing.
encodedData, err = typedData.EncodePrimitiveValue(parsedType, item, depth+1)
} else {
encodedData, err = typedData.encodeArrayValue(item, parsedType, depth+1)
}
if err != nil {
return nil, err
}

View file

@ -1014,3 +1014,49 @@ func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
}
}
var recursiveBytesTypesStandard = apitypes.Types{
"EIP712Domain": {
{
Name: "name",
Type: "string",
},
{
Name: "version",
Type: "string",
},
{
Name: "chainId",
Type: "uint256",
},
{
Name: "verifyingContract",
Type: "address",
},
},
"Val": {
{
Name: "field",
Type: "bytes[][]",
},
},
}
var recursiveBytesMessageStandard = map[string]interface{}{
"field": [][][]byte{{{1}, {2}}, {{3}, {4}}},
}
var recursiveBytesTypedData = apitypes.TypedData{
Types: recursiveBytesTypesStandard,
PrimaryType: "Val",
Domain: domainStandard,
Message: recursiveBytesMessageStandard,
}
func TestEncodeDataRecursiveBytes(t *testing.T) {
typedData := recursiveBytesTypedData
_, err := typedData.EncodeData(typedData.PrimaryType, typedData.Message, 0)
if err != nil {
t.Fatalf("got err %v", err)
}
}

View file

@ -1,5 +1,5 @@
### EIP 712 tests
### EIP-712 tests
These tests are json files which are converted into eip-712 typed data.
These tests are json files which are converted into [EIP-712](https://eips.ethereum.org/EIPS/eip-712) typed data.
All files are expected to be proper json, and tests will fail if they are not.
Files that begin with `expfail' are expected to not pass the hashstruct construction.

View file

@ -431,6 +431,11 @@ var Forks = map[string]*params.ChainConfig{
PragueTime: u64(0),
OsakaTime: u64(0),
DepositContractAddress: params.MainnetChainConfig.DepositContractAddress,
BlobScheduleConfig: &params.BlobScheduleConfig{
Cancun: params.DefaultCancunBlobConfig,
Prague: params.DefaultPragueBlobConfig,
Osaka: params.DefaultOsakaBlobConfig,
},
},
"PragueToOsakaAtTime15k": {
ChainID: big.NewInt(1),
@ -453,6 +458,11 @@ var Forks = map[string]*params.ChainConfig{
PragueTime: u64(0),
OsakaTime: u64(15_000),
DepositContractAddress: params.MainnetChainConfig.DepositContractAddress,
BlobScheduleConfig: &params.BlobScheduleConfig{
Cancun: params.DefaultCancunBlobConfig,
Prague: params.DefaultPragueBlobConfig,
Osaka: params.DefaultOsakaBlobConfig,
},
},
}

View file

@ -310,8 +310,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
evm.SetTxContext(txContext)
// Create "contract" for sender to cache code analysis.
sender := vm.NewContract(vm.AccountRef(msg.From), vm.AccountRef(msg.From),
nil, 0)
sender := vm.NewContract(msg.From, msg.From, nil, 0, nil)
var (
gasUsed uint64
@ -326,7 +325,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
start := time.Now()
// Execute the message.
_, leftOverGas, err := evm.Call(sender, *msg.To, msg.Data, msg.GasLimit, uint256.MustFromBig(msg.Value))
_, leftOverGas, err := evm.Call(sender.Address(), *msg.To, msg.Data, msg.GasLimit, uint256.MustFromBig(msg.Value))
if err != nil {
b.Error(err)
return

View file

@ -37,16 +37,13 @@ func FuzzStackTrie(f *testing.F) {
}
func fuzz(data []byte, debugging bool) {
// This spongeDb is used to check the sequence of disk-db-writes
var (
input = bytes.NewReader(data)
spongeA = &spongeDb{sponge: crypto.NewKeccakState()}
dbA = newTestDatabase(rawdb.NewDatabase(spongeA), rawdb.HashScheme)
trieA = NewEmpty(dbA)
spongeB = &spongeDb{sponge: crypto.NewKeccakState()}
dbB = newTestDatabase(rawdb.NewDatabase(spongeB), rawdb.HashScheme)
trieB = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) {
rawdb.WriteTrieNode(spongeB, common.Hash{}, path, hash, blob, dbB.Scheme())
input = bytes.NewReader(data)
dbA = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
trieA = NewEmpty(dbA)
memDB = rawdb.NewMemoryDatabase()
trieB = NewStackTrie(func(path []byte, hash common.Hash, blob []byte) {
rawdb.WriteTrieNode(memDB, common.Hash{}, path, hash, blob, rawdb.HashScheme)
})
vals []*kv
maxElements = 10000
@ -55,13 +52,17 @@ func fuzz(data []byte, debugging bool) {
)
// Fill the trie with elements
for i := 0; input.Len() > 0 && i < maxElements; i++ {
// Build the key
k := make([]byte, 32)
input.Read(k)
// Build the val
var a uint16
binary.Read(input, binary.LittleEndian, &a)
a = 1 + a%100
v := make([]byte, a)
input.Read(v)
if input.Len() == 0 {
// If it was exhausted while reading, the value may be all zeroes,
// thus 'deletion' which is not supported on stacktrie
@ -73,6 +74,7 @@ func fuzz(data []byte, debugging bool) {
}
keys[string(k)] = struct{}{}
vals = append(vals, &kv{k: k, v: v})
trieA.MustUpdate(k, v)
}
if len(vals) == 0 {
@ -99,11 +101,6 @@ func fuzz(data []byte, debugging bool) {
if rootA != rootB {
panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootB))
}
sumA := spongeA.sponge.Sum(nil)
sumB := spongeB.sponge.Sum(nil)
if !bytes.Equal(sumA, sumB) {
panic(fmt.Sprintf("sequence differ: (trie) %x != %x (stacktrie)", sumA, sumB))
}
// Ensure all the nodes are persisted correctly
var (

View file

@ -779,6 +779,7 @@ func TestCommitAfterHash(t *testing.T) {
func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
// Make the random benchmark deterministic
random := rand.New(rand.NewSource(0))
// Create a realistic account trie to hash
addresses = make([][20]byte, size)
for i := 0; i < len(addresses); i++ {
@ -795,13 +796,18 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
)
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
// and will consume different amount of data from the rand source.
//balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil))
// balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil))
// Therefore, we instead just read via byte buffer
numBytes := random.Uint32() % 33 // [0, 32] bytes
balanceBytes := make([]byte, numBytes)
random.Read(balanceBytes)
balance := new(uint256.Int).SetBytes(balanceBytes)
data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code})
data, _ := rlp.EncodeToBytes(&types.StateAccount{
Nonce: nonce,
Balance: balance,
Root: root,
CodeHash: code,
})
accounts[i] = data
}
return addresses, accounts
@ -856,6 +862,7 @@ func (s *spongeDb) Flush() {
s.sponge.Write([]byte(key))
s.sponge.Write([]byte(s.values[key]))
}
fmt.Println(len(s.keys))
}
// spongeBatch is a dummy batch which immediately writes to the underlying spongedb
@ -873,10 +880,12 @@ func (b *spongeBatch) Write() error { return nil }
func (b *spongeBatch) Reset() {}
func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil }
// TestCommitSequence tests that the trie.Commit operation writes the elements of the trie
// in the expected order.
// The test data was based on the 'master' code, and is basically random. It can be used
// to check whether changes to the trie modifies the write order or data in any way.
// TestCommitSequence tests that the trie.Commit operation writes the elements
// of the trie in the expected order.
//
// The test data was based on the 'master' code, and is basically random.
// It can be used to check whether changes to the trie modifies the write order
// or data in any way.
func TestCommitSequence(t *testing.T) {
for i, tc := range []struct {
count int
@ -887,19 +896,23 @@ func TestCommitSequence(t *testing.T) {
{2000, common.FromHex("4574cd8e6b17f3fe8ad89140d1d0bf4f1bd7a87a8ac3fb623b33550544c77635")},
} {
addresses, accounts := makeAccounts(tc.count)
// This spongeDb is used to check the sequence of disk-db-writes
s := &spongeDb{sponge: crypto.NewKeccakState()}
db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme)
trie := NewEmpty(db)
// Fill the trie with elements
trie := NewEmpty(db)
for i := 0; i < tc.count; i++ {
trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
}
// Flush trie -> database
root, nodes := trie.Commit(false)
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
// Flush memdb -> disk (sponge)
db.Commit(root)
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
t.Errorf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp)
}
@ -917,12 +930,13 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
{200, common.FromHex("dde92ca9812e068e6982d04b40846dc65a61a9fd4996fc0f55f2fde172a8e13c")},
{2000, common.FromHex("ab553a7f9aff82e3929c382908e30ef7dd17a332933e92ba3fe873fc661ef382")},
} {
prng := rand.New(rand.NewSource(int64(i)))
// This spongeDb is used to check the sequence of disk-db-writes
prng := rand.New(rand.NewSource(int64(i)))
s := &spongeDb{sponge: crypto.NewKeccakState()}
db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme)
trie := NewEmpty(db)
// Fill the trie with elements
trie := NewEmpty(db)
for i := 0; i < tc.count; i++ {
key := make([]byte, 32)
var val []byte
@ -939,6 +953,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
// Flush trie -> database
root, nodes := trie.Commit(false)
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
// Flush memdb -> disk (sponge)
db.Commit(root)
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
@ -974,19 +989,22 @@ func TestCommitSequenceStackTrie(t *testing.T) {
// For the stack trie, we need to do inserts in proper order
key := make([]byte, 32)
binary.BigEndian.PutUint64(key, uint64(i))
var val []byte
// 50% short elements, 50% large elements
var val []byte
if prng.Intn(2) == 0 {
val = make([]byte, 1+prng.Intn(32))
} else {
val = make([]byte, 1+prng.Intn(1024))
}
prng.Read(val)
trie.Update(key, val)
stTrie.Update(key, val)
}
// Flush trie -> database
root, nodes := trie.Commit(false)
// Flush memdb -> disk (sponge)
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
db.Commit(root)
@ -1045,6 +1063,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) {
// Flush trie -> database
root, nodes := trie.Commit(false)
// Flush memdb -> disk (sponge)
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
db.Commit(root)

View file

@ -19,6 +19,6 @@ package version
const (
Major = 1 // Major version component of the current release
Minor = 15 // Minor version component of the current release
Patch = 2 // Patch version component of the current release
Patch = 3 // Patch version component of the current release
Meta = "stable" // Version metadata to append to the version string
)