Compare commits
368 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3c696fa1d | ||
|
|
f14f13bac7 | ||
|
|
40fd887df6 | ||
|
|
db6ae7fa12 | ||
|
|
e67d5f8c44 | ||
|
|
cfe25c7a3b | ||
|
|
0a21cb4d21 | ||
|
|
6b61b54dc7 | ||
|
|
283be23817 | ||
|
|
1015a42d90 | ||
|
|
269551876e | ||
|
|
1df75dbe36 | ||
|
|
52a9d89655 | ||
|
|
abbd3d9d21 | ||
|
|
9274f28210 | ||
|
|
bb9897f11b | ||
|
|
93675d1da7 | ||
|
|
b5a88dafae | ||
|
|
80b529ea71 | ||
|
|
55ed8fef0b | ||
|
|
f2e13c7e33 | ||
|
|
2278647ef2 | ||
|
|
564b616163 | ||
|
|
b805772cb4 | ||
|
|
956d32d3e4 | ||
|
|
118c84af57 | ||
|
|
f4c6c033c8 | ||
|
|
9326a118c7 | ||
|
|
b018da9d02 | ||
|
|
deb5c087c4 | ||
|
|
7513966d6e | ||
|
|
c4c2c4fb14 | ||
|
|
868d53c2f2 | ||
|
|
af794ef682 | ||
|
|
c350d3acd5 | ||
|
|
f321dfa827 | ||
|
|
d09600fdf9 | ||
|
|
8032b63f16 | ||
|
|
8dd296201d | ||
|
|
ec596e06a5 | ||
|
|
03424962f1 | ||
|
|
4c4f21293e | ||
|
|
ae707445f5 | ||
|
|
0dd7e82c0a | ||
|
|
07b5a04bd6 | ||
|
|
f544fc3b46 | ||
|
|
9be2e010c1 | ||
|
|
c0b5d428a9 | ||
|
|
7c6b3f9f14 | ||
|
|
a01e9742d9 | ||
|
|
ec69830b6f | ||
|
|
c70b0a9138 | ||
|
|
d71831255d | ||
|
|
88c8459005 | ||
|
|
8f4fac7b86 | ||
|
|
83775b1dc7 | ||
|
|
5035f99bce | ||
|
|
623b17ba20 | ||
|
|
23973bd3a0 | ||
|
|
c3f13b2a1c | ||
|
|
7ef49e350b | ||
|
|
fdb84993d8 | ||
|
|
b0b67be0a2 | ||
|
|
dfd33c7792 | ||
|
|
de597af9c5 | ||
|
|
922eb033d3 | ||
|
|
36a7134367 | ||
|
|
ab3ee99ca9 | ||
|
|
e9467eec1c | ||
|
|
ea3b5095f4 | ||
|
|
0e5546f032 | ||
|
|
9eb91542de | ||
|
|
87377c58bc | ||
|
|
9b5d1412cc | ||
|
|
bfda8ae0c6 | ||
|
|
a223efcf39 | ||
|
|
4e17f28740 | ||
|
|
1d006bd5bf | ||
|
|
0378dc8367 | ||
|
|
eaf4285f0a | ||
|
|
c12a1c9bcf | ||
|
|
020f026616 | ||
|
|
ada20c09dc | ||
|
|
941ae33d7e | ||
|
|
30824faf90 | ||
|
|
733fcbbc65 | ||
|
|
df645e77b7 | ||
|
|
2a534ee133 | ||
|
|
00294e9d28 | ||
|
|
3c37db7989 | ||
|
|
0fde5067c3 | ||
|
|
15fb0dcc67 | ||
|
|
d0fd1331f1 | ||
|
|
693e40a495 | ||
|
|
fc88cea648 | ||
|
|
3b48b16290 | ||
|
|
65aaf52f4c | ||
|
|
84565dc899 | ||
|
|
41b3b30863 | ||
|
|
8486722dcb | ||
|
|
60db6a7b42 | ||
|
|
710c3f32ac | ||
|
|
09d889d2e3 | ||
|
|
43640f12d8 | ||
|
|
6eb42a6b4f | ||
|
|
7a149a159a | ||
|
|
c35684709c | ||
|
|
c4b01d80b9 | ||
|
|
2f2e5b088a | ||
|
|
c686485a06 | ||
|
|
2b9d198706 | ||
|
|
bd57f35f8d | ||
|
|
bc95452e02 | ||
|
|
ab03c5746c | ||
|
|
1cf3b5d38a | ||
|
|
a9523b6428 | ||
|
|
880511dc39 | ||
|
|
5adf4adc8e | ||
|
|
33a13b6f21 | ||
|
|
32a1e0643c | ||
|
|
811a69cd3c | ||
|
|
83e70aa3d0 | ||
|
|
ebe31dfd5c | ||
|
|
d3dae66e59 | ||
|
|
9ea766d6e9 | ||
|
|
4a3aed380e | ||
|
|
978041feea | ||
|
|
b37ac5c102 | ||
|
|
e9981bc6f7 | ||
|
|
dbc1d04f5e | ||
|
|
cf8aa31e3e | ||
|
|
10586952df | ||
|
|
142c94d628 | ||
|
|
16cf5c5fed | ||
|
|
e4675771ed | ||
|
|
67b8137100 | ||
|
|
b635089c7c | ||
|
|
dad8f237ff | ||
|
|
ff6e43e8c4 | ||
|
|
de6d597679 | ||
|
|
6e33dbf96a | ||
|
|
b0f66e34ca | ||
|
|
f94baab238 | ||
|
|
ac0f220040 | ||
|
|
4dfc75deef | ||
|
|
4ad88e9463 | ||
|
|
766ce23032 | ||
|
|
35b4183caa | ||
|
|
1939813ece | ||
|
|
6693fe1be2 | ||
|
|
7026bae17c | ||
|
|
57e6627932 | ||
|
|
ef583e9d18 | ||
|
|
7abe84c8d7 | ||
|
|
380688c636 | ||
|
|
944718bf16 | ||
|
|
df3f0a81a7 | ||
|
|
ad49c708f5 | ||
|
|
f59d013e40 | ||
|
|
c54294bd41 | ||
|
|
15936c64a2 | ||
|
|
b530d8e455 | ||
|
|
0d38b0cd34 | ||
|
|
71210b0630 | ||
|
|
8adce57b41 | ||
|
|
a0d2613ef0 | ||
|
|
169aa91449 | ||
|
|
4bbe993252 | ||
|
|
79d2327771 | ||
|
|
a0631f3ebd | ||
|
|
cf0378499f | ||
|
|
aa55f5ea20 | ||
|
|
bcaf3747f8 | ||
|
|
0aafbb31ab | ||
|
|
803dc6b664 | ||
|
|
37590b2c55 | ||
|
|
10467acc71 | ||
|
|
c4b4d05e69 | ||
|
|
2d9d423764 | ||
|
|
c6cae0f300 | ||
|
|
aadddf3a6e | ||
|
|
640e0f15fd | ||
|
|
6f2e1cff47 | ||
|
|
de366fd2e2 | ||
|
|
09056601d8 | ||
|
|
41abab9e39 | ||
|
|
a4e338f05e | ||
|
|
7cfff30ba3 | ||
|
|
06f1d077d3 | ||
|
|
4939c25341 | ||
|
|
36d67be41b | ||
|
|
19c3c1e205 | ||
|
|
045b9718d5 | ||
|
|
269e80b07e | ||
|
|
9298d2db88 | ||
|
|
98b5930d2d | ||
|
|
ed8fd0ac09 | ||
|
|
73f7e7c087 | ||
|
|
fe0c0b04fe | ||
|
|
0a651f8972 | ||
|
|
d8ea7ac2b0 | ||
|
|
a71f6f91fd | ||
|
|
c10ac4f48f | ||
|
|
e0e45dbc32 | ||
|
|
27654d3022 | ||
|
|
00675c5876 | ||
|
|
27008408a5 | ||
|
|
c11aac249d | ||
|
|
0e3a0a693c | ||
|
|
67a862db9d | ||
|
|
7cf6a63687 | ||
|
|
d8664490da | ||
|
|
c736b04d9b | ||
|
|
115d154392 | ||
|
|
b78d2352ef | ||
|
|
a58e4f0674 | ||
|
|
34b46a2f75 | ||
|
|
fd5078c779 | ||
|
|
86150af2e5 | ||
|
|
69351e8b0f | ||
|
|
3687c34cfc | ||
|
|
1e97148249 | ||
|
|
b6f2bbd417 | ||
|
|
c732039a34 | ||
|
|
caa066dcb0 | ||
|
|
ffb29be7d4 | ||
|
|
3aa874bed2 | ||
|
|
85587d5ef2 | ||
|
|
2eb185c92b | ||
|
|
db273c8733 | ||
|
|
8bda642963 | ||
|
|
349fcdd22d | ||
|
|
1098d148a5 | ||
|
|
deaf10982c | ||
|
|
6a49d13c13 | ||
|
|
4405f18519 | ||
|
|
4461c1fc17 | ||
|
|
0dd173a727 | ||
|
|
85459e1439 | ||
|
|
0750cb0c8f | ||
|
|
cbbfa3eac0 | ||
|
|
6c518fe606 | ||
|
|
bc6569462d | ||
|
|
d09ddac399 | ||
|
|
e85e21c932 | ||
|
|
fc40d68e5b | ||
|
|
5550d8399f | ||
|
|
125fb1ff58 | ||
|
|
682ae838b2 | ||
|
|
68c0ec0815 | ||
|
|
adbbd8cd7b | ||
|
|
a6751d6fc8 | ||
|
|
7270cba25c | ||
|
|
b36c73813c | ||
|
|
50405e29b7 | ||
|
|
d38b88a5a1 | ||
|
|
c9e0b3105b | ||
|
|
d4b81f0e08 | ||
|
|
2613523cb5 | ||
|
|
bdc62f9beb | ||
|
|
5d7d48fc3e | ||
|
|
2262bf3415 | ||
|
|
e015c1116f | ||
|
|
6bb13e8e2b | ||
|
|
2f06c1e854 | ||
|
|
3fef53447f | ||
|
|
94a8b296e4 | ||
|
|
e26fa9e40e | ||
|
|
2f0e63e5ac | ||
|
|
06263b1b35 | ||
|
|
b8cf1636d4 | ||
|
|
153f8da887 | ||
|
|
daf4f72077 | ||
|
|
5534c849b6 | ||
|
|
cc22e0cdf0 | ||
|
|
171430c3f5 | ||
|
|
e517183719 | ||
|
|
af0a3274be | ||
|
|
b88051ec83 | ||
|
|
61932e4710 | ||
|
|
871e55d93e | ||
|
|
42471d7a3e | ||
|
|
caafa93598 | ||
|
|
ea6c16007c | ||
|
|
513276864b | ||
|
|
1a4e4a4fe1 | ||
|
|
7224576fba | ||
|
|
7f5cc02a99 | ||
|
|
d1d9f34e51 | ||
|
|
b6474e9f90 | ||
|
|
64b1cd8aaf | ||
|
|
08fe6a8614 | ||
|
|
61b3d93bb0 | ||
|
|
cc9e2bd9dd | ||
|
|
6a9158bb1b | ||
|
|
70bee977d6 | ||
|
|
b779e469da | ||
|
|
fa581766f5 | ||
|
|
0d4cdb3dbe | ||
|
|
7fd7c1f7dd | ||
|
|
be5df74ed5 | ||
|
|
473ee8fc07 | ||
|
|
7ed52c949e | ||
|
|
d2f00cb54e | ||
|
|
8919c5c0fc | ||
|
|
be3284373f | ||
|
|
5b3e3cd2be | ||
|
|
2ac83e197b | ||
|
|
44a50c9f96 | ||
|
|
47af69c2bc | ||
|
|
603fd898d4 | ||
|
|
e5f5eaebc4 | ||
|
|
74edc93864 | ||
|
|
0e456d9eeb | ||
|
|
6d51c1f5f4 | ||
|
|
ab48ba42f4 | ||
|
|
804afb8faa | ||
|
|
faff03c403 | ||
|
|
1a79f8fe58 | ||
|
|
35b2d07f4b | ||
|
|
eeb22089fd | ||
|
|
14f4228472 | ||
|
|
dd09f7e3fa | ||
|
|
6154f87c33 | ||
|
|
dd4afb9fec | ||
|
|
9ec50080eb | ||
|
|
e96de6489c | ||
|
|
71aa15c98f | ||
|
|
d6e91e2e05 | ||
|
|
e4b8058d5a | ||
|
|
3e896c875a | ||
|
|
43cbcd78ea | ||
|
|
a09a610384 | ||
|
|
905e325cd8 | ||
|
|
86a1f0c394 | ||
|
|
2c67fab0d7 | ||
|
|
fbf6238ae9 | ||
|
|
bc609e852a | ||
|
|
682ee820fa | ||
|
|
9f96e07c1c | ||
|
|
f8820f170c | ||
|
|
45baf21111 | ||
|
|
2e8e35f2ad | ||
|
|
5e07054589 | ||
|
|
bd6bc37eec | ||
|
|
7c7e3a77fc | ||
|
|
ea89f9adf0 | ||
|
|
242b24af9f | ||
|
|
f46c878441 | ||
|
|
c04b8e6d74 | ||
|
|
69f815f6f5 | ||
|
|
fecc8a0f4a | ||
|
|
8c3fc56d7f | ||
|
|
4bdbaab471 | ||
|
|
4253030ef6 | ||
|
|
8d42e115b1 | ||
|
|
ad4fb2c729 | ||
|
|
634d037937 | ||
|
|
a0282fc94f | ||
|
|
1f628d842c | ||
|
|
243cde0f54 | ||
|
|
a13b92524d | ||
|
|
2f6ff492ae | ||
|
|
4f4f9d88d3 | ||
|
|
7362691479 | ||
|
|
ac21f9bfb5 | ||
|
|
0d4c38865e | ||
|
|
938734be3c |
11
.github/CODEOWNERS
vendored
11
.github/CODEOWNERS
vendored
@@ -4,19 +4,22 @@
|
|||||||
accounts/usbwallet @karalabe
|
accounts/usbwallet @karalabe
|
||||||
accounts/scwallet @gballet
|
accounts/scwallet @gballet
|
||||||
accounts/abi @gballet @MariusVanDerWijden
|
accounts/abi @gballet @MariusVanDerWijden
|
||||||
|
beacon/engine @lightclient
|
||||||
cmd/clef @holiman
|
cmd/clef @holiman
|
||||||
|
cmd/evm @holiman @MariusVanDerWijden @lightclient
|
||||||
consensus @karalabe
|
consensus @karalabe
|
||||||
core/ @karalabe @holiman @rjl493456442
|
core/ @karalabe @holiman @rjl493456442
|
||||||
eth/ @karalabe @holiman @rjl493456442
|
eth/ @karalabe @holiman @rjl493456442
|
||||||
eth/catalyst/ @gballet
|
eth/catalyst/ @gballet @lightclient
|
||||||
eth/tracers/ @s1na
|
eth/tracers/ @s1na
|
||||||
|
core/tracing/ @s1na
|
||||||
graphql/ @s1na
|
graphql/ @s1na
|
||||||
|
internal/ethapi @lightclient
|
||||||
|
internal/era @lightclient
|
||||||
les/ @zsfelfoldi @rjl493456442
|
les/ @zsfelfoldi @rjl493456442
|
||||||
light/ @zsfelfoldi @rjl493456442
|
light/ @zsfelfoldi @rjl493456442
|
||||||
node/ @fjl
|
node/ @fjl
|
||||||
p2p/ @fjl @zsfelfoldi
|
p2p/ @fjl @zsfelfoldi
|
||||||
|
params/ @fjl @holiman @karalabe @gballet @rjl493456442 @zsfelfoldi
|
||||||
rpc/ @fjl @holiman
|
rpc/ @fjl @holiman
|
||||||
p2p/simulations @fjl
|
|
||||||
p2p/protocols @fjl
|
|
||||||
p2p/testing @fjl
|
|
||||||
signer/ @holiman
|
signer/ @holiman
|
||||||
|
|||||||
7
.github/workflows/go.yml
vendored
7
.github/workflows/go.yml
vendored
@@ -11,11 +11,12 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: 1.21.4
|
go-version: 1.23.0
|
||||||
|
cache: false
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test -short ./...
|
run: go test -short ./...
|
||||||
env:
|
env:
|
||||||
|
|||||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -28,6 +28,14 @@ build/_vendor/pkg
|
|||||||
/build/bin/
|
/build/bin/
|
||||||
/geth*.zip
|
/geth*.zip
|
||||||
|
|
||||||
|
# used by the build/ci.go archive + upload tool
|
||||||
|
/geth*.tar.gz
|
||||||
|
/geth*.tar.gz.sig
|
||||||
|
/geth*.tar.gz.asc
|
||||||
|
/geth*.zip.sig
|
||||||
|
/geth*.zip.asc
|
||||||
|
|
||||||
|
|
||||||
# travis
|
# travis
|
||||||
profile.tmp
|
profile.tmp
|
||||||
profile.cov
|
profile.cov
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ run:
|
|||||||
# default is true. Enables skipping of directories:
|
# default is true. Enables skipping of directories:
|
||||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||||
skip-dirs-use-default: true
|
skip-dirs-use-default: true
|
||||||
skip-files:
|
|
||||||
- core/genesis_alloc.go
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
@@ -25,7 +23,10 @@ linters:
|
|||||||
- durationcheck
|
- durationcheck
|
||||||
- exportloopref
|
- exportloopref
|
||||||
- whitespace
|
- whitespace
|
||||||
|
- revive # only certain checks enabled
|
||||||
|
|
||||||
|
### linters we tried and will not be using:
|
||||||
|
###
|
||||||
# - structcheck # lots of false positives
|
# - structcheck # lots of false positives
|
||||||
# - errcheck #lot of false positives
|
# - errcheck #lot of false positives
|
||||||
# - contextcheck
|
# - contextcheck
|
||||||
@@ -38,21 +39,35 @@ linters:
|
|||||||
linters-settings:
|
linters-settings:
|
||||||
gofmt:
|
gofmt:
|
||||||
simplify: true
|
simplify: true
|
||||||
|
revive:
|
||||||
|
enable-all-rules: false
|
||||||
|
# here we enable specific useful rules
|
||||||
|
# see https://golangci-lint.run/usage/linters/#revive for supported rules
|
||||||
|
rules:
|
||||||
|
- name: receiver-naming
|
||||||
|
severity: warning
|
||||||
|
disabled: false
|
||||||
|
exclude: [""]
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
|
exclude-files:
|
||||||
|
- core/genesis_alloc.go
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
- path: crypto/bn256/cloudflare/optate.go
|
- path: crypto/bn256/cloudflare/optate.go
|
||||||
linters:
|
linters:
|
||||||
- deadcode
|
- deadcode
|
||||||
- staticcheck
|
- staticcheck
|
||||||
|
- path: crypto/bn256/
|
||||||
|
linters:
|
||||||
|
- revive
|
||||||
|
- path: cmd/utils/flags.go
|
||||||
|
text: "SA1019: cfg.TxLookupLimit is deprecated: use 'TransactionHistory' instead."
|
||||||
|
- path: cmd/utils/flags.go
|
||||||
|
text: "SA1019: ethconfig.Defaults.TxLookupLimit is deprecated: use 'TransactionHistory' instead."
|
||||||
- path: internal/build/pgp.go
|
- path: internal/build/pgp.go
|
||||||
text: 'SA1019: "golang.org/x/crypto/openpgp" is deprecated: this package is unmaintained except for security fixes.'
|
text: 'SA1019: "golang.org/x/crypto/openpgp" is deprecated: this package is unmaintained except for security fixes.'
|
||||||
- path: core/vm/contracts.go
|
- path: core/vm/contracts.go
|
||||||
text: 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated: RIPEMD-160 is a legacy hash and should not be used for new applications.'
|
text: 'SA1019: "golang.org/x/crypto/ripemd160" is deprecated: RIPEMD-160 is a legacy hash and should not be used for new applications.'
|
||||||
- path: accounts/usbwallet/trezor.go
|
|
||||||
text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.'
|
|
||||||
- path: accounts/usbwallet/trezor/
|
|
||||||
text: 'SA1019: "github.com/golang/protobuf/proto" is deprecated: Use the "google.golang.org/protobuf/proto" package instead.'
|
|
||||||
exclude:
|
exclude:
|
||||||
- 'SA1019: event.TypeMux is deprecated: use Feed'
|
- 'SA1019: event.TypeMux is deprecated: use Feed'
|
||||||
- 'SA1019: strings.Title is deprecated'
|
- 'SA1019: strings.Title is deprecated'
|
||||||
|
|||||||
100
.travis.yml
100
.travis.yml
@@ -9,14 +9,13 @@ jobs:
|
|||||||
- azure-osx
|
- azure-osx
|
||||||
|
|
||||||
include:
|
include:
|
||||||
# These builders create the Docker sub-images for multi-arch push and each
|
# This builder create and push the Docker images for all architectures
|
||||||
# will attempt to push the multi-arch image if they are the last builder
|
|
||||||
- stage: build
|
- stage: build
|
||||||
if: type = push
|
if: type = push
|
||||||
os: linux
|
os: linux
|
||||||
arch: amd64
|
arch: amd64
|
||||||
dist: bionic
|
dist: focal
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
env:
|
env:
|
||||||
- docker
|
- docker
|
||||||
services:
|
services:
|
||||||
@@ -26,44 +25,27 @@ jobs:
|
|||||||
before_install:
|
before_install:
|
||||||
- export DOCKER_CLI_EXPERIMENTAL=enabled
|
- export DOCKER_CLI_EXPERIMENTAL=enabled
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
|
- go run build/ci.go dockerx -platform "linux/amd64,linux/arm64" -upload ethereum/client-go
|
||||||
|
|
||||||
- stage: build
|
|
||||||
if: type = push
|
|
||||||
os: linux
|
|
||||||
arch: arm64
|
|
||||||
dist: bionic
|
|
||||||
go: 1.22.x
|
|
||||||
env:
|
|
||||||
- docker
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
git:
|
|
||||||
submodules: false # avoid cloning ethereum/tests
|
|
||||||
before_install:
|
|
||||||
- export DOCKER_CLI_EXPERIMENTAL=enabled
|
|
||||||
script:
|
|
||||||
- go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
|
|
||||||
|
|
||||||
# This builder does the Linux Azure uploads
|
# This builder does the Linux Azure uploads
|
||||||
- stage: build
|
- stage: build
|
||||||
if: type = push
|
if: type = push
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: focal
|
||||||
sudo: required
|
sudo: required
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
env:
|
env:
|
||||||
- azure-linux
|
- azure-linux
|
||||||
git:
|
git:
|
||||||
submodules: false # avoid cloning ethereum/tests
|
submodules: false # avoid cloning ethereum/tests
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- gcc-multilib
|
|
||||||
script:
|
script:
|
||||||
# Build for the primary platforms that Trusty can manage
|
# build amd64
|
||||||
- go run build/ci.go install -dlgo
|
- go run build/ci.go install -dlgo
|
||||||
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
- go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
||||||
|
|
||||||
|
# build 386
|
||||||
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
|
||||||
|
- git status --porcelain
|
||||||
- go run build/ci.go install -dlgo -arch 386
|
- go run build/ci.go install -dlgo -arch 386
|
||||||
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
- go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
||||||
|
|
||||||
@@ -85,12 +67,13 @@ jobs:
|
|||||||
if: type = push
|
if: type = push
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode14.2
|
osx_image: xcode14.2
|
||||||
go: 1.22.x
|
go: 1.23.1 # See https://github.com/ethereum/go-ethereum/pull/30478
|
||||||
env:
|
env:
|
||||||
- azure-osx
|
- azure-osx
|
||||||
git:
|
git:
|
||||||
submodules: false # avoid cloning ethereum/tests
|
submodules: false # avoid cloning ethereum/tests
|
||||||
script:
|
script:
|
||||||
|
- ln -sf /Users/travis/gopath/bin/go1.23.1 /usr/local/bin/go # Work around travis go-setup bug
|
||||||
- go run build/ci.go install -dlgo
|
- go run build/ci.go install -dlgo
|
||||||
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
- go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -signify SIGNIFY_KEY -upload gethstore/builds
|
||||||
- go run build/ci.go install -dlgo -arch arm64
|
- go run build/ci.go install -dlgo -arch arm64
|
||||||
@@ -98,48 +81,34 @@ jobs:
|
|||||||
|
|
||||||
# These builders run the tests
|
# These builders run the tests
|
||||||
- stage: build
|
- stage: build
|
||||||
|
if: type = push
|
||||||
os: linux
|
os: linux
|
||||||
arch: amd64
|
arch: amd64
|
||||||
dist: bionic
|
dist: focal
|
||||||
|
go: 1.23.x
|
||||||
|
script:
|
||||||
|
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
|
||||||
|
|
||||||
|
- stage: build
|
||||||
|
if: type = push
|
||||||
|
os: linux
|
||||||
|
dist: focal
|
||||||
go: 1.22.x
|
go: 1.22.x
|
||||||
script:
|
script:
|
||||||
- travis_wait 30 go run build/ci.go test $TEST_PACKAGES
|
- travis_wait 45 go run build/ci.go test $TEST_PACKAGES
|
||||||
|
|
||||||
- stage: build
|
|
||||||
if: type = pull_request
|
|
||||||
os: linux
|
|
||||||
arch: arm64
|
|
||||||
dist: bionic
|
|
||||||
go: 1.21.x
|
|
||||||
script:
|
|
||||||
- travis_wait 30 go run build/ci.go test $TEST_PACKAGES
|
|
||||||
|
|
||||||
- stage: build
|
|
||||||
os: linux
|
|
||||||
dist: bionic
|
|
||||||
go: 1.21.x
|
|
||||||
script:
|
|
||||||
- travis_wait 30 go run build/ci.go test $TEST_PACKAGES
|
|
||||||
|
|
||||||
# This builder does the Ubuntu PPA nightly uploads
|
# This builder does the Ubuntu PPA nightly uploads
|
||||||
- stage: build
|
- stage: build
|
||||||
if: type = cron || (type = push && tag ~= /^v[0-9]/)
|
if: type = cron || (type = push && tag ~= /^v[0-9]/)
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: focal
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
env:
|
env:
|
||||||
- ubuntu-ppa
|
- ubuntu-ppa
|
||||||
git:
|
git:
|
||||||
submodules: false # avoid cloning ethereum/tests
|
submodules: false # avoid cloning ethereum/tests
|
||||||
addons:
|
before_install:
|
||||||
apt:
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends install devscripts debhelper dput fakeroot
|
||||||
packages:
|
|
||||||
- devscripts
|
|
||||||
- debhelper
|
|
||||||
- dput
|
|
||||||
- fakeroot
|
|
||||||
- python-bzrlib
|
|
||||||
- python-paramiko
|
|
||||||
script:
|
script:
|
||||||
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
|
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
|
||||||
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
|
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
|
||||||
@@ -148,8 +117,8 @@ jobs:
|
|||||||
- stage: build
|
- stage: build
|
||||||
if: type = cron
|
if: type = cron
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: focal
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
env:
|
env:
|
||||||
- azure-purge
|
- azure-purge
|
||||||
git:
|
git:
|
||||||
@@ -161,8 +130,9 @@ jobs:
|
|||||||
- stage: build
|
- stage: build
|
||||||
if: type = cron
|
if: type = cron
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: focal
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
|
env:
|
||||||
|
- racetests
|
||||||
script:
|
script:
|
||||||
- travis_wait 30 go run build/ci.go test -race $TEST_PACKAGES
|
- travis_wait 60 go run build/ci.go test -race $TEST_PACKAGES
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ ARG VERSION=""
|
|||||||
ARG BUILDNUM=""
|
ARG BUILDNUM=""
|
||||||
|
|
||||||
# Build Geth in a stock Go builder container
|
# Build Geth in a stock Go builder container
|
||||||
FROM golang:1.22-alpine as builder
|
FROM golang:1.23-alpine AS builder
|
||||||
|
|
||||||
RUN apk add --no-cache gcc musl-dev linux-headers git
|
RUN apk add --no-cache gcc musl-dev linux-headers git
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ ARG VERSION=""
|
|||||||
ARG BUILDNUM=""
|
ARG BUILDNUM=""
|
||||||
|
|
||||||
# Build Geth in a stock Go builder container
|
# Build Geth in a stock Go builder container
|
||||||
FROM golang:1.22-alpine as builder
|
FROM golang:1.23-alpine AS builder
|
||||||
|
|
||||||
RUN apk add --no-cache gcc musl-dev linux-headers git
|
RUN apk add --no-cache gcc musl-dev linux-headers git
|
||||||
|
|
||||||
@@ -14,6 +14,13 @@ COPY go.sum /go-ethereum/
|
|||||||
RUN cd /go-ethereum && go mod download
|
RUN cd /go-ethereum && go mod download
|
||||||
|
|
||||||
ADD . /go-ethereum
|
ADD . /go-ethereum
|
||||||
|
|
||||||
|
# This is not strictly necessary, but it matches the "Dockerfile" steps, thus
|
||||||
|
# makes it so that under certain circumstances, the docker layer can be cached,
|
||||||
|
# and the builder can jump to the next (build all) command, with the go cache fully loaded.
|
||||||
|
#
|
||||||
|
RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth
|
||||||
|
|
||||||
RUN cd /go-ethereum && go run build/ci.go install -static
|
RUN cd /go-ethereum && go run build/ci.go install -static
|
||||||
|
|
||||||
# Pull all binaries into a second stage deploy alpine container
|
# Pull all binaries into a second stage deploy alpine container
|
||||||
|
|||||||
26
Makefile
26
Makefile
@@ -2,31 +2,35 @@
|
|||||||
# with Go source code. If you know what GOPATH is then you probably
|
# with Go source code. If you know what GOPATH is then you probably
|
||||||
# don't need to bother with make.
|
# don't need to bother with make.
|
||||||
|
|
||||||
.PHONY: geth all test lint clean devtools help
|
.PHONY: geth all test lint fmt clean devtools help
|
||||||
|
|
||||||
GOBIN = ./build/bin
|
GOBIN = ./build/bin
|
||||||
GO ?= latest
|
GO ?= latest
|
||||||
GORUN = go run
|
GORUN = go run
|
||||||
|
|
||||||
#? geth: Build geth
|
#? geth: Build geth.
|
||||||
geth:
|
geth:
|
||||||
$(GORUN) build/ci.go install ./cmd/geth
|
$(GORUN) build/ci.go install ./cmd/geth
|
||||||
@echo "Done building."
|
@echo "Done building."
|
||||||
@echo "Run \"$(GOBIN)/geth\" to launch geth."
|
@echo "Run \"$(GOBIN)/geth\" to launch geth."
|
||||||
|
|
||||||
#? all: Build all packages and executables
|
#? all: Build all packages and executables.
|
||||||
all:
|
all:
|
||||||
$(GORUN) build/ci.go install
|
$(GORUN) build/ci.go install
|
||||||
|
|
||||||
#? test: Run the tests
|
#? test: Run the tests.
|
||||||
test: all
|
test: all
|
||||||
$(GORUN) build/ci.go test
|
$(GORUN) build/ci.go test
|
||||||
|
|
||||||
#? lint: Run certain pre-selected linters
|
#? lint: Run certain pre-selected linters.
|
||||||
lint: ## Run linters.
|
lint: ## Run linters.
|
||||||
$(GORUN) build/ci.go lint
|
$(GORUN) build/ci.go lint
|
||||||
|
|
||||||
#? clean: Clean go cache, built executables, and the auto generated folder
|
#? fmt: Ensure consistent code formatting.
|
||||||
|
fmt:
|
||||||
|
gofmt -s -w $(shell find . -name "*.go")
|
||||||
|
|
||||||
|
#? clean: Clean go cache, built executables, and the auto generated folder.
|
||||||
clean:
|
clean:
|
||||||
go clean -cache
|
go clean -cache
|
||||||
rm -fr build/_workspace/pkg/ $(GOBIN)/*
|
rm -fr build/_workspace/pkg/ $(GOBIN)/*
|
||||||
@@ -34,16 +38,20 @@ clean:
|
|||||||
# The devtools target installs tools required for 'go generate'.
|
# The devtools target installs tools required for 'go generate'.
|
||||||
# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'.
|
# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'.
|
||||||
|
|
||||||
#? devtools: Install recommended developer tools
|
#? devtools: Install recommended developer tools.
|
||||||
devtools:
|
devtools:
|
||||||
env GOBIN= go install golang.org/x/tools/cmd/stringer@latest
|
env GOBIN= go install golang.org/x/tools/cmd/stringer@latest
|
||||||
env GOBIN= go install github.com/fjl/gencodec@latest
|
env GOBIN= go install github.com/fjl/gencodec@latest
|
||||||
env GOBIN= go install github.com/golang/protobuf/protoc-gen-go@latest
|
env GOBIN= go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||||
env GOBIN= go install ./cmd/abigen
|
env GOBIN= go install ./cmd/abigen
|
||||||
@type "solc" 2> /dev/null || echo 'Please install solc'
|
@type "solc" 2> /dev/null || echo 'Please install solc'
|
||||||
@type "protoc" 2> /dev/null || echo 'Please install protoc'
|
@type "protoc" 2> /dev/null || echo 'Please install protoc'
|
||||||
|
|
||||||
#? help: Get more info on make commands.
|
#? help: Get more info on make commands.
|
||||||
help: Makefile
|
help: Makefile
|
||||||
@echo " Choose a command run in go-ethereum:"
|
@echo ''
|
||||||
|
@echo 'Usage:'
|
||||||
|
@echo ' make [target]'
|
||||||
|
@echo ''
|
||||||
|
@echo 'Targets:'
|
||||||
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
|
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -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).
|
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.21 or later) and a C compiler. You can install
|
Building `geth` requires both a Go (version 1.22 or later) and a C compiler. You can install
|
||||||
them using your favourite package manager. Once the dependencies are installed, run
|
them using your favourite package manager. Once the dependencies are installed, run
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -89,7 +89,7 @@ This command will:
|
|||||||
This tool is optional and if you leave it out you can always attach it to an already running
|
This tool is optional and if you leave it out you can always attach it to an already running
|
||||||
`geth` instance with `geth attach`.
|
`geth` instance with `geth attach`.
|
||||||
|
|
||||||
### A Full node on the Görli test network
|
### A Full node on the Holesky test network
|
||||||
|
|
||||||
Transitioning towards developers, if you'd like to play around with creating Ethereum
|
Transitioning towards developers, if you'd like to play around with creating Ethereum
|
||||||
contracts, you almost certainly would like to do that without any real money involved until
|
contracts, you almost certainly would like to do that without any real money involved until
|
||||||
@@ -98,23 +98,23 @@ network, you want to join the **test** network with your node, which is fully eq
|
|||||||
the main network, but with play-Ether only.
|
the main network, but with play-Ether only.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ geth --goerli console
|
$ geth --holesky console
|
||||||
```
|
```
|
||||||
|
|
||||||
The `console` subcommand has the same meaning as above and is equally
|
The `console` subcommand has the same meaning as above and is equally
|
||||||
useful on the testnet too.
|
useful on the testnet too.
|
||||||
|
|
||||||
Specifying the `--goerli` flag, however, will reconfigure your `geth` instance a bit:
|
Specifying the `--holesky` flag, however, will reconfigure your `geth` instance a bit:
|
||||||
|
|
||||||
* Instead of connecting to the main Ethereum network, the client will connect to the Görli
|
* Instead of connecting to the main Ethereum network, the client will connect to the Holesky
|
||||||
test network, which uses different P2P bootnodes, different network IDs and genesis
|
test network, which uses different P2P bootnodes, different network IDs and genesis
|
||||||
states.
|
states.
|
||||||
* Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth`
|
* Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth`
|
||||||
will nest itself one level deeper into a `goerli` subfolder (`~/.ethereum/goerli` on
|
will nest itself one level deeper into a `holesky` subfolder (`~/.ethereum/holesky` on
|
||||||
Linux). Note, on OSX and Linux this also means that attaching to a running testnet node
|
Linux). Note, on OSX and Linux this also means that attaching to a running testnet node
|
||||||
requires the use of a custom endpoint since `geth attach` will try to attach to a
|
requires the use of a custom endpoint since `geth attach` will try to attach to a
|
||||||
production node endpoint by default, e.g.,
|
production node endpoint by default, e.g.,
|
||||||
`geth attach <datadir>/goerli/geth.ipc`. Windows users are not affected by
|
`geth attach <datadir>/holesky/geth.ipc`. Windows users are not affected by
|
||||||
this.
|
this.
|
||||||
|
|
||||||
*Note: Although some internal protective measures prevent transactions from
|
*Note: Although some internal protective measures prevent transactions from
|
||||||
|
|||||||
@@ -171,5 +171,5 @@ i4O1UeWKs9owWttan9+PI47ozBSKOTxmMqLSQ0f56Np9FJsV0ilGxRKfjhzJ4KniOMUBA7mP
|
|||||||
epy6lH7HmxjjOR7eo0DaSxQGQpThAtFGwkWkFh8yki8j3E42kkrxvEyyYZDXn2YcI3bpqhJx
|
epy6lH7HmxjjOR7eo0DaSxQGQpThAtFGwkWkFh8yki8j3E42kkrxvEyyYZDXn2YcI3bpqhJx
|
||||||
PtwCMZUJ3kc/skOrs6bOI19iBNaEoNX5Dllm7UHjOgWNDQkcCuOCxucKano=
|
PtwCMZUJ3kc/skOrs6bOI19iBNaEoNX5Dllm7UHjOgWNDQkcCuOCxucKano=
|
||||||
=arte
|
=arte
|
||||||
-----END PGP PUBLIC KEY BLOCK------
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1218,3 +1218,10 @@ func TestUnpackRevert(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInternalContractType(t *testing.T) {
|
||||||
|
jsonData := `[{"inputs":[{"components":[{"internalType":"uint256","name":"dailyLimit","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"accountDailyLimit","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"onlyWhitelisted","type":"bool"}],"internalType":"struct IMessagePassingBridge.BridgeLimits","name":"bridgeLimits","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.AccountLimit","name":"accountDailyLimit","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.BridgeDailyLimit","name":"bridgeDailyLimit","type":"tuple"},{"internalType":"contract INameService","name":"nameService","type":"INameService"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"canBridge","outputs":[{"internalType":"bool","name":"isWithinLimit","type":"bool"},{"internalType":"string","name":"error","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFrom18ToTokenDecimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFromTokenTo18Decimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"}]`
|
||||||
|
if _, err := JSON(strings.NewReader(jsonData)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,11 +59,12 @@ type TransactOpts struct {
|
|||||||
Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state)
|
Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state)
|
||||||
Signer SignerFn // Method to use for signing the transaction (mandatory)
|
Signer SignerFn // Method to use for signing the transaction (mandatory)
|
||||||
|
|
||||||
Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
|
Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
|
||||||
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
|
GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
|
||||||
GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
|
GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
|
||||||
GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
|
GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
|
||||||
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
|
GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
|
||||||
|
AccessList types.AccessList // Access list to set for the transaction execution (nil = no access list)
|
||||||
|
|
||||||
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
|
Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
|
||||||
|
|
||||||
@@ -300,20 +301,21 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
baseTx := &types.DynamicFeeTx{
|
baseTx := &types.DynamicFeeTx{
|
||||||
To: contract,
|
To: contract,
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
GasFeeCap: gasFeeCap,
|
GasFeeCap: gasFeeCap,
|
||||||
GasTipCap: gasTipCap,
|
GasTipCap: gasTipCap,
|
||||||
Gas: gasLimit,
|
Gas: gasLimit,
|
||||||
Value: value,
|
Value: value,
|
||||||
Data: input,
|
Data: input,
|
||||||
|
AccessList: opts.AccessList,
|
||||||
}
|
}
|
||||||
return types.NewTx(baseTx), nil
|
return types.NewTx(baseTx), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
|
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
|
||||||
if opts.GasFeeCap != nil || opts.GasTipCap != nil {
|
if opts.GasFeeCap != nil || opts.GasTipCap != nil || opts.AccessList != nil {
|
||||||
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas or accessList specified but london is not active yet")
|
||||||
}
|
}
|
||||||
// Normalize value
|
// Normalize value
|
||||||
value := opts.Value
|
value := opts.Value
|
||||||
|
|||||||
487
accounts/abi/bind/source.go.tpl
Normal file
487
accounts/abi/bind/source.go.tpl
Normal file
@@ -0,0 +1,487 @@
|
|||||||
|
// Code generated - DO NOT EDIT.
|
||||||
|
// This file is a generated binding and any manual changes will be lost.
|
||||||
|
|
||||||
|
package {{.Package}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
ethereum "github.com/ethereum/go-ethereum"
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/event"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var (
|
||||||
|
_ = errors.New
|
||||||
|
_ = big.NewInt
|
||||||
|
_ = strings.NewReader
|
||||||
|
_ = ethereum.NotFound
|
||||||
|
_ = bind.Bind
|
||||||
|
_ = common.Big1
|
||||||
|
_ = types.BloomLookup
|
||||||
|
_ = event.NewSubscription
|
||||||
|
_ = abi.ConvertType
|
||||||
|
)
|
||||||
|
|
||||||
|
{{$structs := .Structs}}
|
||||||
|
{{range $structs}}
|
||||||
|
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
||||||
|
type {{.Name}} struct {
|
||||||
|
{{range $field := .Fields}}
|
||||||
|
{{$field.Name}} {{$field.Type}}{{end}}
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{range $contract := .Contracts}}
|
||||||
|
// {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract.
|
||||||
|
var {{.Type}}MetaData = &bind.MetaData{
|
||||||
|
ABI: "{{.InputABI}}",
|
||||||
|
{{if $contract.FuncSigs -}}
|
||||||
|
Sigs: map[string]string{
|
||||||
|
{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
|
||||||
|
{{end}}
|
||||||
|
},
|
||||||
|
{{end -}}
|
||||||
|
{{if .InputBin -}}
|
||||||
|
Bin: "0x{{.InputBin}}",
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
||||||
|
// Deprecated: Use {{.Type}}MetaData.ABI instead.
|
||||||
|
var {{.Type}}ABI = {{.Type}}MetaData.ABI
|
||||||
|
|
||||||
|
{{if $contract.FuncSigs}}
|
||||||
|
// Deprecated: Use {{.Type}}MetaData.Sigs instead.
|
||||||
|
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
|
||||||
|
var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .InputBin}}
|
||||||
|
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
||||||
|
// Deprecated: Use {{.Type}}MetaData.Bin instead.
|
||||||
|
var {{.Type}}Bin = {{.Type}}MetaData.Bin
|
||||||
|
|
||||||
|
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
|
||||||
|
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
|
||||||
|
parsed, err := {{.Type}}MetaData.GetAbi()
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, nil, nil, err
|
||||||
|
}
|
||||||
|
if parsed == nil {
|
||||||
|
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
|
||||||
|
}
|
||||||
|
{{range $pattern, $name := .Libraries}}
|
||||||
|
{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
|
||||||
|
{{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:])
|
||||||
|
{{end}}
|
||||||
|
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, nil, nil, err
|
||||||
|
}
|
||||||
|
return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
// {{.Type}} is an auto generated Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}} struct {
|
||||||
|
{{.Type}}Caller // Read-only binding to the contract
|
||||||
|
{{.Type}}Transactor // Write-only binding to the contract
|
||||||
|
{{.Type}}Filterer // Log filterer for contract events
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}}Caller struct {
|
||||||
|
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}}Transactor struct {
|
||||||
|
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
|
||||||
|
type {{.Type}}Filterer struct {
|
||||||
|
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}Session is an auto generated Go binding around an Ethereum contract,
|
||||||
|
// with pre-set call and transact options.
|
||||||
|
type {{.Type}}Session struct {
|
||||||
|
Contract *{{.Type}} // Generic contract binding to set the session for
|
||||||
|
CallOpts bind.CallOpts // Call options to use throughout this session
|
||||||
|
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract,
|
||||||
|
// with pre-set call options.
|
||||||
|
type {{.Type}}CallerSession struct {
|
||||||
|
Contract *{{.Type}}Caller // Generic contract caller binding to set the session for
|
||||||
|
CallOpts bind.CallOpts // Call options to use throughout this session
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
|
||||||
|
// with pre-set transact options.
|
||||||
|
type {{.Type}}TransactorSession struct {
|
||||||
|
Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for
|
||||||
|
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}}Raw struct {
|
||||||
|
Contract *{{.Type}} // Generic contract binding to access the raw methods on
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}}CallerRaw struct {
|
||||||
|
Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
|
||||||
|
type {{.Type}}TransactorRaw struct {
|
||||||
|
Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on
|
||||||
|
}
|
||||||
|
|
||||||
|
// New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract.
|
||||||
|
func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) {
|
||||||
|
contract, err := bind{{.Type}}(address, backend, backend, backend)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract.
|
||||||
|
func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) {
|
||||||
|
contract, err := bind{{.Type}}(address, caller, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &{{.Type}}Caller{contract: contract}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract.
|
||||||
|
func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) {
|
||||||
|
contract, err := bind{{.Type}}(address, nil, transactor, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &{{.Type}}Transactor{contract: contract}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract.
|
||||||
|
func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) {
|
||||||
|
contract, err := bind{{.Type}}(address, nil, nil, filterer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &{{.Type}}Filterer{contract: contract}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind{{.Type}} binds a generic wrapper to an already deployed contract.
|
||||||
|
func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
|
||||||
|
parsed, err := {{.Type}}MetaData.GetAbi()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call invokes the (constant) contract method with params as input values and
|
||||||
|
// sets the output to result. The result type might be a single field for simple
|
||||||
|
// returns, a slice of interfaces for anonymous returns and a struct for named
|
||||||
|
// returns.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
||||||
|
return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer initiates a plain transaction to move funds to the contract, calling
|
||||||
|
// its default method if one is available.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transact invokes the (paid) contract method with params as input values.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call invokes the (constant) contract method with params as input values and
|
||||||
|
// sets the output to result. The result type might be a single field for simple
|
||||||
|
// returns, a slice of interfaces for anonymous returns and a struct for named
|
||||||
|
// returns.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
||||||
|
return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer initiates a plain transaction to move funds to the contract, calling
|
||||||
|
// its default method if one is available.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.contract.Transfer(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transact invokes the (paid) contract method with params as input values.
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{range .Calls}}
|
||||||
|
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) {
|
||||||
|
var out []interface{}
|
||||||
|
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
{{if .Structured}}
|
||||||
|
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
|
||||||
|
if err != nil {
|
||||||
|
return *outstruct, err
|
||||||
|
}
|
||||||
|
{{range $i, $t := .Normalized.Outputs}}
|
||||||
|
outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
|
||||||
|
|
||||||
|
return *outstruct, err
|
||||||
|
{{else}}
|
||||||
|
if err != nil {
|
||||||
|
return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err
|
||||||
|
}
|
||||||
|
{{range $i, $t := .Normalized.Outputs}}
|
||||||
|
out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
|
||||||
|
|
||||||
|
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{range .Transacts}}
|
||||||
|
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .Fallback}}
|
||||||
|
// Fallback is a paid mutator transaction binding the contract fallback function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Fallback.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.contract.RawTransact(opts, calldata)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback is a paid mutator transaction binding the contract fallback function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Fallback.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback is a paid mutator transaction binding the contract fallback function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Fallback.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .Receive}}
|
||||||
|
// Receive is a paid mutator transaction binding the contract receive function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Receive.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive is a paid mutator transaction binding the contract receive function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Receive.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive is a paid mutator transaction binding the contract receive function.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Receive.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) {
|
||||||
|
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{range .Events}}
|
||||||
|
// {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract.
|
||||||
|
type {{$contract.Type}}{{.Normalized.Name}}Iterator struct {
|
||||||
|
Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log
|
||||||
|
|
||||||
|
contract *bind.BoundContract // Generic contract to use for unpacking event data
|
||||||
|
event string // Event name to use for unpacking event data
|
||||||
|
|
||||||
|
logs chan types.Log // Log channel receiving the found contract events
|
||||||
|
sub ethereum.Subscription // Subscription for errors, completion and termination
|
||||||
|
done bool // Whether the subscription completed delivering logs
|
||||||
|
fail error // Occurred error to stop iteration
|
||||||
|
}
|
||||||
|
// Next advances the iterator to the subsequent event, returning whether there
|
||||||
|
// are any more events found. In case of a retrieval or parsing error, false is
|
||||||
|
// returned and Error() can be queried for the exact failure.
|
||||||
|
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool {
|
||||||
|
// If the iterator failed, stop iterating
|
||||||
|
if (it.fail != nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// If the iterator completed, deliver directly whatever's available
|
||||||
|
if (it.done) {
|
||||||
|
select {
|
||||||
|
case log := <-it.logs:
|
||||||
|
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
|
||||||
|
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
|
||||||
|
it.fail = err
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
it.Event.Raw = log
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Iterator still in progress, wait for either a data or an error event
|
||||||
|
select {
|
||||||
|
case log := <-it.logs:
|
||||||
|
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
|
||||||
|
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
|
||||||
|
it.fail = err
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
it.Event.Raw = log
|
||||||
|
return true
|
||||||
|
|
||||||
|
case err := <-it.sub.Err():
|
||||||
|
it.done = true
|
||||||
|
it.fail = err
|
||||||
|
return it.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Error returns any retrieval or parsing error occurred during filtering.
|
||||||
|
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error {
|
||||||
|
return it.fail
|
||||||
|
}
|
||||||
|
// Close terminates the iteration process, releasing any pending underlying
|
||||||
|
// resources.
|
||||||
|
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error {
|
||||||
|
it.sub.Unsubscribe()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract.
|
||||||
|
type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}}
|
||||||
|
{{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}}
|
||||||
|
Raw types.Log // Blockchain specific contextual infos
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) {
|
||||||
|
{{range .Normalized.Inputs}}
|
||||||
|
{{if .Indexed}}var {{.Name}}Rule []interface{}
|
||||||
|
for _, {{.Name}}Item := range {{.Name}} {
|
||||||
|
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
|
||||||
|
}{{end}}{{end}}
|
||||||
|
|
||||||
|
logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) {
|
||||||
|
{{range .Normalized.Inputs}}
|
||||||
|
{{if .Indexed}}var {{.Name}}Rule []interface{}
|
||||||
|
for _, {{.Name}}Item := range {{.Name}} {
|
||||||
|
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
|
||||||
|
}{{end}}{{end}}
|
||||||
|
|
||||||
|
logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return event.NewSubscription(func(quit <-chan struct{}) error {
|
||||||
|
defer sub.Unsubscribe()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case log := <-logs:
|
||||||
|
// New log arrived, parse the event and forward to the user
|
||||||
|
event := new({{$contract.Type}}{{.Normalized.Name}})
|
||||||
|
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
event.Raw = log
|
||||||
|
|
||||||
|
select {
|
||||||
|
case sink <- event:
|
||||||
|
case err := <-sub.Err():
|
||||||
|
return err
|
||||||
|
case <-quit:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case err := <-sub.Err():
|
||||||
|
return err
|
||||||
|
case <-quit:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
||||||
|
//
|
||||||
|
// Solidity: {{.Original.String}}
|
||||||
|
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
|
||||||
|
event := new({{$contract.Type}}{{.Normalized.Name}})
|
||||||
|
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
event.Raw = log
|
||||||
|
return event, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@@ -16,7 +16,11 @@
|
|||||||
|
|
||||||
package bind
|
package bind
|
||||||
|
|
||||||
import "github.com/ethereum/go-ethereum/accounts/abi"
|
import (
|
||||||
|
_ "embed"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
)
|
||||||
|
|
||||||
// tmplData is the data structure required to fill the binding template.
|
// tmplData is the data structure required to fill the binding template.
|
||||||
type tmplData struct {
|
type tmplData struct {
|
||||||
@@ -80,492 +84,6 @@ var tmplSource = map[Lang]string{
|
|||||||
|
|
||||||
// tmplSourceGo is the Go source template that the generated Go contract binding
|
// tmplSourceGo is the Go source template that the generated Go contract binding
|
||||||
// is based on.
|
// is based on.
|
||||||
const tmplSourceGo = `
|
//
|
||||||
// Code generated - DO NOT EDIT.
|
//go:embed source.go.tpl
|
||||||
// This file is a generated binding and any manual changes will be lost.
|
var tmplSourceGo string
|
||||||
|
|
||||||
package {{.Package}}
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/big"
|
|
||||||
"strings"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
ethereum "github.com/ethereum/go-ethereum"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
|
||||||
var (
|
|
||||||
_ = errors.New
|
|
||||||
_ = big.NewInt
|
|
||||||
_ = strings.NewReader
|
|
||||||
_ = ethereum.NotFound
|
|
||||||
_ = bind.Bind
|
|
||||||
_ = common.Big1
|
|
||||||
_ = types.BloomLookup
|
|
||||||
_ = event.NewSubscription
|
|
||||||
_ = abi.ConvertType
|
|
||||||
)
|
|
||||||
|
|
||||||
{{$structs := .Structs}}
|
|
||||||
{{range $structs}}
|
|
||||||
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
|
||||||
type {{.Name}} struct {
|
|
||||||
{{range $field := .Fields}}
|
|
||||||
{{$field.Name}} {{$field.Type}}{{end}}
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{range $contract := .Contracts}}
|
|
||||||
// {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract.
|
|
||||||
var {{.Type}}MetaData = &bind.MetaData{
|
|
||||||
ABI: "{{.InputABI}}",
|
|
||||||
{{if $contract.FuncSigs -}}
|
|
||||||
Sigs: map[string]string{
|
|
||||||
{{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
|
|
||||||
{{end}}
|
|
||||||
},
|
|
||||||
{{end -}}
|
|
||||||
{{if .InputBin -}}
|
|
||||||
Bin: "0x{{.InputBin}}",
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
|
||||||
// Deprecated: Use {{.Type}}MetaData.ABI instead.
|
|
||||||
var {{.Type}}ABI = {{.Type}}MetaData.ABI
|
|
||||||
|
|
||||||
{{if $contract.FuncSigs}}
|
|
||||||
// Deprecated: Use {{.Type}}MetaData.Sigs instead.
|
|
||||||
// {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
|
|
||||||
var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .InputBin}}
|
|
||||||
// {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
|
|
||||||
// Deprecated: Use {{.Type}}MetaData.Bin instead.
|
|
||||||
var {{.Type}}Bin = {{.Type}}MetaData.Bin
|
|
||||||
|
|
||||||
// Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
|
|
||||||
func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
|
|
||||||
parsed, err := {{.Type}}MetaData.GetAbi()
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, nil, nil, err
|
|
||||||
}
|
|
||||||
if parsed == nil {
|
|
||||||
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
|
|
||||||
}
|
|
||||||
{{range $pattern, $name := .Libraries}}
|
|
||||||
{{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
|
|
||||||
{{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:])
|
|
||||||
{{end}}
|
|
||||||
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
|
|
||||||
if err != nil {
|
|
||||||
return common.Address{}, nil, nil, err
|
|
||||||
}
|
|
||||||
return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
// {{.Type}} is an auto generated Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}} struct {
|
|
||||||
{{.Type}}Caller // Read-only binding to the contract
|
|
||||||
{{.Type}}Transactor // Write-only binding to the contract
|
|
||||||
{{.Type}}Filterer // Log filterer for contract events
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}}Caller struct {
|
|
||||||
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}}Transactor struct {
|
|
||||||
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
|
|
||||||
type {{.Type}}Filterer struct {
|
|
||||||
contract *bind.BoundContract // Generic contract wrapper for the low level calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}Session is an auto generated Go binding around an Ethereum contract,
|
|
||||||
// with pre-set call and transact options.
|
|
||||||
type {{.Type}}Session struct {
|
|
||||||
Contract *{{.Type}} // Generic contract binding to set the session for
|
|
||||||
CallOpts bind.CallOpts // Call options to use throughout this session
|
|
||||||
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract,
|
|
||||||
// with pre-set call options.
|
|
||||||
type {{.Type}}CallerSession struct {
|
|
||||||
Contract *{{.Type}}Caller // Generic contract caller binding to set the session for
|
|
||||||
CallOpts bind.CallOpts // Call options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
|
|
||||||
// with pre-set transact options.
|
|
||||||
type {{.Type}}TransactorSession struct {
|
|
||||||
Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for
|
|
||||||
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}}Raw struct {
|
|
||||||
Contract *{{.Type}} // Generic contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}}CallerRaw struct {
|
|
||||||
Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
|
|
||||||
type {{.Type}}TransactorRaw struct {
|
|
||||||
Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract.
|
|
||||||
func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) {
|
|
||||||
contract, err := bind{{.Type}}(address, backend, backend, backend)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract.
|
|
||||||
func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) {
|
|
||||||
contract, err := bind{{.Type}}(address, caller, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &{{.Type}}Caller{contract: contract}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract.
|
|
||||||
func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) {
|
|
||||||
contract, err := bind{{.Type}}(address, nil, transactor, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &{{.Type}}Transactor{contract: contract}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract.
|
|
||||||
func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) {
|
|
||||||
contract, err := bind{{.Type}}(address, nil, nil, filterer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &{{.Type}}Filterer{contract: contract}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// bind{{.Type}} binds a generic wrapper to an already deployed contract.
|
|
||||||
func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
|
|
||||||
parsed, err := {{.Type}}MetaData.GetAbi()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call invokes the (constant) contract method with params as input values and
|
|
||||||
// sets the output to result. The result type might be a single field for simple
|
|
||||||
// returns, a slice of interfaces for anonymous returns and a struct for named
|
|
||||||
// returns.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
|
||||||
return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer initiates a plain transaction to move funds to the contract, calling
|
|
||||||
// its default method if one is available.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transact invokes the (paid) contract method with params as input values.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call invokes the (constant) contract method with params as input values and
|
|
||||||
// sets the output to result. The result type might be a single field for simple
|
|
||||||
// returns, a slice of interfaces for anonymous returns and a struct for named
|
|
||||||
// returns.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
|
|
||||||
return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer initiates a plain transaction to move funds to the contract, calling
|
|
||||||
// its default method if one is available.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.contract.Transfer(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transact invokes the (paid) contract method with params as input values.
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
{{range .Calls}}
|
|
||||||
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) {
|
|
||||||
var out []interface{}
|
|
||||||
err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
{{if .Structured}}
|
|
||||||
outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} })
|
|
||||||
if err != nil {
|
|
||||||
return *outstruct, err
|
|
||||||
}
|
|
||||||
{{range $i, $t := .Normalized.Outputs}}
|
|
||||||
outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
|
|
||||||
|
|
||||||
return *outstruct, err
|
|
||||||
{{else}}
|
|
||||||
if err != nil {
|
|
||||||
return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err
|
|
||||||
}
|
|
||||||
{{range $i, $t := .Normalized.Outputs}}
|
|
||||||
out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}}
|
|
||||||
|
|
||||||
return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{range .Transacts}}
|
|
||||||
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .Fallback}}
|
|
||||||
// Fallback is a paid mutator transaction binding the contract fallback function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Fallback.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.contract.RawTransact(opts, calldata)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback is a paid mutator transaction binding the contract fallback function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Fallback.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback is a paid mutator transaction binding the contract fallback function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Fallback.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata)
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .Receive}}
|
|
||||||
// Receive is a paid mutator transaction binding the contract receive function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Receive.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive is a paid mutator transaction binding the contract receive function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Receive.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Receive is a paid mutator transaction binding the contract receive function.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Receive.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) {
|
|
||||||
return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts)
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{range .Events}}
|
|
||||||
// {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract.
|
|
||||||
type {{$contract.Type}}{{.Normalized.Name}}Iterator struct {
|
|
||||||
Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log
|
|
||||||
|
|
||||||
contract *bind.BoundContract // Generic contract to use for unpacking event data
|
|
||||||
event string // Event name to use for unpacking event data
|
|
||||||
|
|
||||||
logs chan types.Log // Log channel receiving the found contract events
|
|
||||||
sub ethereum.Subscription // Subscription for errors, completion and termination
|
|
||||||
done bool // Whether the subscription completed delivering logs
|
|
||||||
fail error // Occurred error to stop iteration
|
|
||||||
}
|
|
||||||
// Next advances the iterator to the subsequent event, returning whether there
|
|
||||||
// are any more events found. In case of a retrieval or parsing error, false is
|
|
||||||
// returned and Error() can be queried for the exact failure.
|
|
||||||
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool {
|
|
||||||
// If the iterator failed, stop iterating
|
|
||||||
if (it.fail != nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// If the iterator completed, deliver directly whatever's available
|
|
||||||
if (it.done) {
|
|
||||||
select {
|
|
||||||
case log := <-it.logs:
|
|
||||||
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
|
|
||||||
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
|
|
||||||
it.fail = err
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
it.Event.Raw = log
|
|
||||||
return true
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Iterator still in progress, wait for either a data or an error event
|
|
||||||
select {
|
|
||||||
case log := <-it.logs:
|
|
||||||
it.Event = new({{$contract.Type}}{{.Normalized.Name}})
|
|
||||||
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
|
|
||||||
it.fail = err
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
it.Event.Raw = log
|
|
||||||
return true
|
|
||||||
|
|
||||||
case err := <-it.sub.Err():
|
|
||||||
it.done = true
|
|
||||||
it.fail = err
|
|
||||||
return it.Next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Error returns any retrieval or parsing error occurred during filtering.
|
|
||||||
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error {
|
|
||||||
return it.fail
|
|
||||||
}
|
|
||||||
// Close terminates the iteration process, releasing any pending underlying
|
|
||||||
// resources.
|
|
||||||
func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error {
|
|
||||||
it.sub.Unsubscribe()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract.
|
|
||||||
type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}}
|
|
||||||
{{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}}
|
|
||||||
Raw types.Log // Blockchain specific contextual infos
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) {
|
|
||||||
{{range .Normalized.Inputs}}
|
|
||||||
{{if .Indexed}}var {{.Name}}Rule []interface{}
|
|
||||||
for _, {{.Name}}Item := range {{.Name}} {
|
|
||||||
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
|
|
||||||
}{{end}}{{end}}
|
|
||||||
|
|
||||||
logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) {
|
|
||||||
{{range .Normalized.Inputs}}
|
|
||||||
{{if .Indexed}}var {{.Name}}Rule []interface{}
|
|
||||||
for _, {{.Name}}Item := range {{.Name}} {
|
|
||||||
{{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
|
|
||||||
}{{end}}{{end}}
|
|
||||||
|
|
||||||
logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return event.NewSubscription(func(quit <-chan struct{}) error {
|
|
||||||
defer sub.Unsubscribe()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case log := <-logs:
|
|
||||||
// New log arrived, parse the event and forward to the user
|
|
||||||
event := new({{$contract.Type}}{{.Normalized.Name}})
|
|
||||||
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
event.Raw = log
|
|
||||||
|
|
||||||
select {
|
|
||||||
case sink <- event:
|
|
||||||
case err := <-sub.Err():
|
|
||||||
return err
|
|
||||||
case <-quit:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case err := <-sub.Err():
|
|
||||||
return err
|
|
||||||
case <-quit:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}.
|
|
||||||
//
|
|
||||||
// Solidity: {{.Original.String}}
|
|
||||||
func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
|
|
||||||
event := new({{$contract.Type}}{{.Normalized.Name}})
|
|
||||||
if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
event.Raw = log
|
|
||||||
return event, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
`
|
|
||||||
|
|||||||
@@ -82,7 +82,9 @@ func TestWaitDeployed(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Send and mine the transaction.
|
// Send and mine the transaction.
|
||||||
backend.Client().SendTransaction(ctx, tx)
|
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
|
||||||
|
t.Errorf("test %q: failed to send transaction: %v", name, err)
|
||||||
|
}
|
||||||
backend.Commit()
|
backend.Commit()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@@ -116,7 +118,9 @@ func TestWaitDeployedCornerCases(t *testing.T) {
|
|||||||
tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
|
tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
backend.Client().SendTransaction(ctx, tx)
|
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
|
||||||
|
t.Errorf("failed to send transaction: %q", err)
|
||||||
|
}
|
||||||
backend.Commit()
|
backend.Commit()
|
||||||
notContractCreation := errors.New("tx is not contract creation")
|
notContractCreation := errors.New("tx is not contract creation")
|
||||||
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() {
|
if _, err := bind.WaitDeployed(ctx, backend.Client(), tx); err.Error() != notContractCreation.Error() {
|
||||||
@@ -134,6 +138,8 @@ func TestWaitDeployedCornerCases(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
backend.Client().SendTransaction(ctx, tx)
|
if err := backend.Client().SendTransaction(ctx, tx); err != nil {
|
||||||
|
t.Errorf("failed to send transaction: %q", err)
|
||||||
|
}
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ type Type struct {
|
|||||||
var (
|
var (
|
||||||
// typeRegex parses the abi sub types
|
// typeRegex parses the abi sub types
|
||||||
typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
|
typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
|
||||||
|
|
||||||
|
// sliceSizeRegex grab the slice size
|
||||||
|
sliceSizeRegex = regexp.MustCompile("[0-9]+")
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewType creates a new reflection type of abi type given in t.
|
// NewType creates a new reflection type of abi type given in t.
|
||||||
@@ -91,8 +94,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
|||||||
// grab the last cell and create a type from there
|
// grab the last cell and create a type from there
|
||||||
sliced := t[i:]
|
sliced := t[i:]
|
||||||
// grab the slice size with regexp
|
// grab the slice size with regexp
|
||||||
re := regexp.MustCompile("[0-9]+")
|
intz := sliceSizeRegex.FindAllString(sliced, -1)
|
||||||
intz := re.FindAllString(sliced, -1)
|
|
||||||
|
|
||||||
if len(intz) == 0 {
|
if len(intz) == 0 {
|
||||||
// is a slice
|
// is a slice
|
||||||
@@ -217,7 +219,12 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
|||||||
typ.T = FunctionTy
|
typ.T = FunctionTy
|
||||||
typ.Size = 24
|
typ.Size = 24
|
||||||
default:
|
default:
|
||||||
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
|
if strings.HasPrefix(internalType, "contract ") {
|
||||||
|
typ.Size = 20
|
||||||
|
typ.T = AddressTy
|
||||||
|
} else {
|
||||||
|
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func TestWatchNewFile(t *testing.T) {
|
|||||||
func TestWatchNoDir(t *testing.T) {
|
func TestWatchNoDir(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Create ks but not the directory that it watches.
|
// Create ks but not the directory that it watches.
|
||||||
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
|
dir := filepath.Join(t.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int()))
|
||||||
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
|
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
|
||||||
list := ks.Accounts()
|
list := ks.Accounts()
|
||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
@@ -126,7 +126,6 @@ func TestWatchNoDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Create the directory and copy a key file into it.
|
// Create the directory and copy a key file into it.
|
||||||
os.MkdirAll(dir, 0700)
|
os.MkdirAll(dir, 0700)
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
file := filepath.Join(dir, "aaa")
|
file := filepath.Join(dir, "aaa")
|
||||||
if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil {
|
if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -325,7 +324,8 @@ func TestUpdatedKeyfileContents(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create a temporary keystore to test with
|
// Create a temporary keystore to test with
|
||||||
dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int()))
|
dir := t.TempDir()
|
||||||
|
|
||||||
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
|
ks := NewKeyStore(dir, LightScryptN, LightScryptP)
|
||||||
|
|
||||||
list := ks.Accounts()
|
list := ks.Accounts()
|
||||||
@@ -335,9 +335,7 @@ func TestUpdatedKeyfileContents(t *testing.T) {
|
|||||||
if !waitWatcherStart(ks) {
|
if !waitWatcherStart(ks) {
|
||||||
t.Fatal("keystore watcher didn't start in time")
|
t.Fatal("keystore watcher didn't start in time")
|
||||||
}
|
}
|
||||||
// Create the directory and copy a key file into it.
|
// Copy a key file into it
|
||||||
os.MkdirAll(dir, 0700)
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
file := filepath.Join(dir, "aaa")
|
file := filepath.Join(dir, "aaa")
|
||||||
|
|
||||||
// Place one of our testfiles in there
|
// Place one of our testfiles in there
|
||||||
|
|||||||
@@ -312,11 +312,10 @@ func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error {
|
|||||||
// Lock removes the private key with the given address from memory.
|
// Lock removes the private key with the given address from memory.
|
||||||
func (ks *KeyStore) Lock(addr common.Address) error {
|
func (ks *KeyStore) Lock(addr common.Address) error {
|
||||||
ks.mu.Lock()
|
ks.mu.Lock()
|
||||||
if unl, found := ks.unlocked[addr]; found {
|
unl, found := ks.unlocked[addr]
|
||||||
ks.mu.Unlock()
|
ks.mu.Unlock()
|
||||||
|
if found {
|
||||||
ks.expire(addr, unl, time.Duration(0)*time.Nanosecond)
|
ks.expire(addr, unl, time.Duration(0)*time.Nanosecond)
|
||||||
} else {
|
|
||||||
ks.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ func (hub *Hub) readPairings() error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer pairingFile.Close()
|
||||||
|
|
||||||
pairingData, err := io.ReadAll(pairingFile)
|
pairingData, err := io.ReadAll(pairingFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -73,6 +73,14 @@ var (
|
|||||||
DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes())
|
DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// PinRegexp is the regular expression used to validate PIN codes.
|
||||||
|
pinRegexp = regexp.MustCompile(`^[0-9]{6,}$`)
|
||||||
|
|
||||||
|
// PukRegexp is the regular expression used to validate PUK codes.
|
||||||
|
pukRegexp = regexp.MustCompile(`^[0-9]{12,}$`)
|
||||||
|
)
|
||||||
|
|
||||||
// List of APDU command-related constants
|
// List of APDU command-related constants
|
||||||
const (
|
const (
|
||||||
claISO7816 = 0
|
claISO7816 = 0
|
||||||
@@ -380,7 +388,7 @@ func (w *Wallet) Open(passphrase string) error {
|
|||||||
case passphrase == "":
|
case passphrase == "":
|
||||||
return ErrPINUnblockNeeded
|
return ErrPINUnblockNeeded
|
||||||
case status.PinRetryCount > 0:
|
case status.PinRetryCount > 0:
|
||||||
if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) {
|
if !pinRegexp.MatchString(passphrase) {
|
||||||
w.log.Error("PIN needs to be at least 6 digits")
|
w.log.Error("PIN needs to be at least 6 digits")
|
||||||
return ErrPINNeeded
|
return ErrPINNeeded
|
||||||
}
|
}
|
||||||
@@ -388,7 +396,7 @@ func (w *Wallet) Open(passphrase string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) {
|
if !pukRegexp.MatchString(passphrase) {
|
||||||
w.log.Error("PUK needs to be at least 12 digits")
|
w.log.Error("PUK needs to be at least 12 digits")
|
||||||
return ErrPINUnblockNeeded
|
return ErrPINUnblockNeeded
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/golang/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
|
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,8 @@
|
|||||||
syntax = "proto2";
|
syntax = "proto2";
|
||||||
package hw.trezor.messages.common;
|
package hw.trezor.messages.common;
|
||||||
|
|
||||||
|
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response: Success of the previous request
|
* Response: Success of the previous request
|
||||||
* @end
|
* @end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,8 @@
|
|||||||
syntax = "proto2";
|
syntax = "proto2";
|
||||||
package hw.trezor.messages.ethereum;
|
package hw.trezor.messages.ethereum;
|
||||||
|
|
||||||
|
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||||
|
|
||||||
// Sugar for easier handling in Java
|
// Sugar for easier handling in Java
|
||||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||||
option java_outer_classname = "TrezorMessageEthereum";
|
option java_outer_classname = "TrezorMessageEthereum";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,8 @@
|
|||||||
syntax = "proto2";
|
syntax = "proto2";
|
||||||
package hw.trezor.messages.management;
|
package hw.trezor.messages.management;
|
||||||
|
|
||||||
|
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||||
|
|
||||||
// Sugar for easier handling in Java
|
// Sugar for easier handling in Java
|
||||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||||
option java_outer_classname = "TrezorMessageManagement";
|
option java_outer_classname = "TrezorMessageManagement";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,13 @@ package hw.trezor.messages;
|
|||||||
* Messages for TREZOR communication
|
* Messages for TREZOR communication
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||||
|
|
||||||
// Sugar for easier handling in Java
|
// Sugar for easier handling in Java
|
||||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||||
option java_outer_classname = "TrezorMessage";
|
option java_outer_classname = "TrezorMessage";
|
||||||
|
|
||||||
|
|
||||||
import "google/protobuf/descriptor.proto";
|
import "google/protobuf/descriptor.proto";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,10 +39,10 @@
|
|||||||
// - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases
|
// - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases
|
||||||
// - Build with the usual `./configure && make` and ensure it's on your $PATH
|
// - Build with the usual `./configure && make` and ensure it's on your $PATH
|
||||||
// - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor
|
// - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor
|
||||||
// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go`
|
// - Grab the latest Go plugin `go get -u google.golang.org/protobuf/cmd/protoc-gen-go`
|
||||||
// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...`
|
// - Vendor in the latest Go plugin `govendor fetch google.golang.org/protobuf/...`
|
||||||
|
|
||||||
//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto
|
//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto
|
||||||
|
|
||||||
// Package trezor contains the wire protocol.
|
// Package trezor contains the wire protocol.
|
||||||
package trezor
|
package trezor
|
||||||
@@ -50,7 +50,7 @@ package trezor
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type returns the protocol buffer type number of a specific message. If the
|
// Type returns the protocol buffer type number of a specific message. If the
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ for:
|
|||||||
- image: Ubuntu
|
- image: Ubuntu
|
||||||
build_script:
|
build_script:
|
||||||
- go run build/ci.go lint
|
- go run build/ci.go lint
|
||||||
|
- go run build/ci.go generate -verify
|
||||||
- go run build/ci.go install -dlgo
|
- go run build/ci.go install -dlgo
|
||||||
test_script:
|
test_script:
|
||||||
- go run build/ci.go test -dlgo -short
|
- go run build/ci.go test -dlgo -short
|
||||||
|
|||||||
@@ -70,7 +70,10 @@ func TestBlockSync(t *testing.T) {
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
var expNumber, headNumber uint64
|
var expNumber, headNumber uint64
|
||||||
if expHead != nil {
|
if expHead != nil {
|
||||||
p, _ := expHead.ExecutionPayload()
|
p, err := expHead.ExecutionPayload()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expHead.ExecutionPayload() failed: %v", err)
|
||||||
|
}
|
||||||
expNumber = p.NumberU64()
|
expNumber = p.NumberU64()
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -56,32 +56,17 @@ var (
|
|||||||
AddFork("DENEB", 132608, []byte{144, 0, 0, 115}),
|
AddFork("DENEB", 132608, []byte{144, 0, 0, 115}),
|
||||||
Checkpoint: common.HexToHash("0x1005a6d9175e96bfbce4d35b80f468e9bff0b674e1e861d16e09e10005a58e81"),
|
Checkpoint: common.HexToHash("0x1005a6d9175e96bfbce4d35b80f468e9bff0b674e1e861d16e09e10005a58e81"),
|
||||||
}
|
}
|
||||||
|
|
||||||
GoerliConfig = lightClientConfig{
|
|
||||||
ChainConfig: (&types.ChainConfig{
|
|
||||||
GenesisValidatorsRoot: common.HexToHash("0x043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb"),
|
|
||||||
GenesisTime: 1614588812,
|
|
||||||
}).
|
|
||||||
AddFork("GENESIS", 0, []byte{0, 0, 16, 32}).
|
|
||||||
AddFork("ALTAIR", 36660, []byte{1, 0, 16, 32}).
|
|
||||||
AddFork("BELLATRIX", 112260, []byte{2, 0, 16, 32}).
|
|
||||||
AddFork("CAPELLA", 162304, []byte{3, 0, 16, 32}).
|
|
||||||
AddFork("DENEB", 231680, []byte{4, 0, 16, 32}),
|
|
||||||
Checkpoint: common.HexToHash("0x53a0f4f0a378e2c4ae0a9ee97407eb69d0d737d8d8cd0a5fb1093f42f7b81c49"),
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeChainConfig(ctx *cli.Context) lightClientConfig {
|
func makeChainConfig(ctx *cli.Context) lightClientConfig {
|
||||||
var config lightClientConfig
|
var config lightClientConfig
|
||||||
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
|
customConfig := ctx.IsSet(utils.BeaconConfigFlag.Name)
|
||||||
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.GoerliFlag, utils.SepoliaFlag, utils.BeaconConfigFlag)
|
utils.CheckExclusive(ctx, utils.MainnetFlag, utils.SepoliaFlag, utils.BeaconConfigFlag)
|
||||||
switch {
|
switch {
|
||||||
case ctx.Bool(utils.MainnetFlag.Name):
|
case ctx.Bool(utils.MainnetFlag.Name):
|
||||||
config = MainnetConfig
|
config = MainnetConfig
|
||||||
case ctx.Bool(utils.SepoliaFlag.Name):
|
case ctx.Bool(utils.SepoliaFlag.Name):
|
||||||
config = SepoliaConfig
|
config = SepoliaConfig
|
||||||
case ctx.Bool(utils.GoerliFlag.Name):
|
|
||||||
config = GoerliConfig
|
|
||||||
default:
|
default:
|
||||||
if !customConfig {
|
if !customConfig {
|
||||||
config = MainnetConfig
|
config = MainnetConfig
|
||||||
|
|||||||
@@ -17,23 +17,25 @@ var _ = (*executableDataMarshaling)(nil)
|
|||||||
// MarshalJSON marshals as JSON.
|
// MarshalJSON marshals as JSON.
|
||||||
func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
||||||
type ExecutableData struct {
|
type ExecutableData struct {
|
||||||
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
||||||
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
|
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
|
||||||
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
|
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
|
||||||
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
|
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
|
||||||
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
|
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
|
||||||
Random common.Hash `json:"prevRandao" gencodec:"required"`
|
Random common.Hash `json:"prevRandao" gencodec:"required"`
|
||||||
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
|
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
|
||||||
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
|
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
|
||||||
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
||||||
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
|
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
|
||||||
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
|
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
|
||||||
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
|
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
|
||||||
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
||||||
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
|
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
|
||||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||||
|
Deposits types.Deposits `json:"depositRequests"`
|
||||||
|
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||||
}
|
}
|
||||||
var enc ExecutableData
|
var enc ExecutableData
|
||||||
enc.ParentHash = e.ParentHash
|
enc.ParentHash = e.ParentHash
|
||||||
@@ -58,29 +60,33 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||||||
enc.Withdrawals = e.Withdrawals
|
enc.Withdrawals = e.Withdrawals
|
||||||
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
|
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
|
||||||
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
|
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
|
||||||
|
enc.Deposits = e.Deposits
|
||||||
|
enc.ExecutionWitness = e.ExecutionWitness
|
||||||
return json.Marshal(&enc)
|
return json.Marshal(&enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON unmarshals from JSON.
|
// UnmarshalJSON unmarshals from JSON.
|
||||||
func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
||||||
type ExecutableData struct {
|
type ExecutableData struct {
|
||||||
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
|
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
|
||||||
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
|
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
|
||||||
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
|
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
|
||||||
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
|
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
|
||||||
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
|
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
|
||||||
Random *common.Hash `json:"prevRandao" gencodec:"required"`
|
Random *common.Hash `json:"prevRandao" gencodec:"required"`
|
||||||
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
|
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
|
||||||
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
|
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
|
||||||
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
|
||||||
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
|
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
|
||||||
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
|
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
|
||||||
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
|
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
|
||||||
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
|
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
|
||||||
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
|
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
|
||||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||||
|
Deposits *types.Deposits `json:"depositRequests"`
|
||||||
|
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||||
}
|
}
|
||||||
var dec ExecutableData
|
var dec ExecutableData
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
@@ -154,5 +160,11 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||||||
if dec.ExcessBlobGas != nil {
|
if dec.ExcessBlobGas != nil {
|
||||||
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
|
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
|
||||||
}
|
}
|
||||||
|
if dec.Deposits != nil {
|
||||||
|
e.Deposits = *dec.Deposits
|
||||||
|
}
|
||||||
|
if dec.ExecutionWitness != nil {
|
||||||
|
e.ExecutionWitness = dec.ExecutionWitness
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
|||||||
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
||||||
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
||||||
Override bool `json:"shouldOverrideBuilder"`
|
Override bool `json:"shouldOverrideBuilder"`
|
||||||
|
Witness *hexutil.Bytes `json:"witness"`
|
||||||
}
|
}
|
||||||
var enc ExecutionPayloadEnvelope
|
var enc ExecutionPayloadEnvelope
|
||||||
enc.ExecutionPayload = e.ExecutionPayload
|
enc.ExecutionPayload = e.ExecutionPayload
|
||||||
enc.BlockValue = (*hexutil.Big)(e.BlockValue)
|
enc.BlockValue = (*hexutil.Big)(e.BlockValue)
|
||||||
enc.BlobsBundle = e.BlobsBundle
|
enc.BlobsBundle = e.BlobsBundle
|
||||||
enc.Override = e.Override
|
enc.Override = e.Override
|
||||||
|
enc.Witness = e.Witness
|
||||||
return json.Marshal(&enc)
|
return json.Marshal(&enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
|
|||||||
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
||||||
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
||||||
Override *bool `json:"shouldOverrideBuilder"`
|
Override *bool `json:"shouldOverrideBuilder"`
|
||||||
|
Witness *hexutil.Bytes `json:"witness"`
|
||||||
}
|
}
|
||||||
var dec ExecutionPayloadEnvelope
|
var dec ExecutionPayloadEnvelope
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
if err := json.Unmarshal(input, &dec); err != nil {
|
||||||
@@ -54,5 +57,8 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
|
|||||||
if dec.Override != nil {
|
if dec.Override != nil {
|
||||||
e.Override = *dec.Override
|
e.Override = *dec.Override
|
||||||
}
|
}
|
||||||
|
if dec.Witness != nil {
|
||||||
|
e.Witness = dec.Witness
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,23 +59,25 @@ type payloadAttributesMarshaling struct {
|
|||||||
|
|
||||||
// ExecutableData is the data necessary to execute an EL payload.
|
// ExecutableData is the data necessary to execute an EL payload.
|
||||||
type ExecutableData struct {
|
type ExecutableData struct {
|
||||||
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
||||||
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
|
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
|
||||||
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
|
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
|
||||||
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
|
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
|
||||||
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
|
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
|
||||||
Random common.Hash `json:"prevRandao" gencodec:"required"`
|
Random common.Hash `json:"prevRandao" gencodec:"required"`
|
||||||
Number uint64 `json:"blockNumber" gencodec:"required"`
|
Number uint64 `json:"blockNumber" gencodec:"required"`
|
||||||
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
|
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
|
||||||
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
|
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
|
||||||
Timestamp uint64 `json:"timestamp" gencodec:"required"`
|
Timestamp uint64 `json:"timestamp" gencodec:"required"`
|
||||||
ExtraData []byte `json:"extraData" gencodec:"required"`
|
ExtraData []byte `json:"extraData" gencodec:"required"`
|
||||||
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
|
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
|
||||||
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
|
||||||
Transactions [][]byte `json:"transactions" gencodec:"required"`
|
Transactions [][]byte `json:"transactions" gencodec:"required"`
|
||||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||||
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
||||||
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
||||||
|
Deposits types.Deposits `json:"depositRequests"`
|
||||||
|
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON type overrides for executableData.
|
// JSON type overrides for executableData.
|
||||||
@@ -91,6 +94,14 @@ type executableDataMarshaling struct {
|
|||||||
ExcessBlobGas *hexutil.Uint64
|
ExcessBlobGas *hexutil.Uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatelessPayloadStatusV1 is the result of a stateless payload execution.
|
||||||
|
type StatelessPayloadStatusV1 struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
StateRoot common.Hash `json:"stateRoot"`
|
||||||
|
ReceiptsRoot common.Hash `json:"receiptsRoot"`
|
||||||
|
ValidationError *string `json:"validationError"`
|
||||||
|
}
|
||||||
|
|
||||||
//go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
|
//go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
|
||||||
|
|
||||||
type ExecutionPayloadEnvelope struct {
|
type ExecutionPayloadEnvelope struct {
|
||||||
@@ -98,6 +109,7 @@ type ExecutionPayloadEnvelope struct {
|
|||||||
BlockValue *big.Int `json:"blockValue" gencodec:"required"`
|
BlockValue *big.Int `json:"blockValue" gencodec:"required"`
|
||||||
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
|
||||||
Override bool `json:"shouldOverrideBuilder"`
|
Override bool `json:"shouldOverrideBuilder"`
|
||||||
|
Witness *hexutil.Bytes `json:"witness"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlobsBundleV1 struct {
|
type BlobsBundleV1 struct {
|
||||||
@@ -112,9 +124,10 @@ type executionPayloadEnvelopeMarshaling struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PayloadStatusV1 struct {
|
type PayloadStatusV1 struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
LatestValidHash *common.Hash `json:"latestValidHash"`
|
Witness *hexutil.Bytes `json:"witness"`
|
||||||
ValidationError *string `json:"validationError"`
|
LatestValidHash *common.Hash `json:"latestValidHash"`
|
||||||
|
ValidationError *string `json:"validationError"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransitionConfigurationV1 struct {
|
type TransitionConfigurationV1 struct {
|
||||||
@@ -193,23 +206,37 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
|
|||||||
//
|
//
|
||||||
// and that the blockhash of the constructed block matches the parameters. Nil
|
// and that the blockhash of the constructed block matches the parameters. Nil
|
||||||
// Withdrawals value will propagate through the returned block. Empty
|
// Withdrawals value will propagate through the returned block. Empty
|
||||||
// Withdrawals value must be passed via non-nil, length 0 value in params.
|
// Withdrawals value must be passed via non-nil, length 0 value in data.
|
||||||
func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) {
|
func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) {
|
||||||
txs, err := decodeTransactions(params.Transactions)
|
block, err := ExecutableDataToBlockNoHash(data, versionedHashes, beaconRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(params.ExtraData) > 32 {
|
if block.Hash() != data.BlockHash {
|
||||||
return nil, fmt.Errorf("invalid extradata length: %v", len(params.ExtraData))
|
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", data.BlockHash, block.Hash())
|
||||||
}
|
}
|
||||||
if len(params.LogsBloom) != 256 {
|
return block, nil
|
||||||
return nil, fmt.Errorf("invalid logsBloom length: %v", len(params.LogsBloom))
|
}
|
||||||
|
|
||||||
|
// ExecutableDataToBlockNoHash is analogous to ExecutableDataToBlock, but is used
|
||||||
|
// for stateless execution, so it skips checking if the executable data hashes to
|
||||||
|
// the requested hash (stateless has to *compute* the root hash, it's not given).
|
||||||
|
func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (*types.Block, error) {
|
||||||
|
txs, err := decodeTransactions(data.Transactions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(data.ExtraData) > int(params.MaximumExtraDataSize) {
|
||||||
|
return nil, fmt.Errorf("invalid extradata length: %v", len(data.ExtraData))
|
||||||
|
}
|
||||||
|
if len(data.LogsBloom) != 256 {
|
||||||
|
return nil, fmt.Errorf("invalid logsBloom length: %v", len(data.LogsBloom))
|
||||||
}
|
}
|
||||||
// Check that baseFeePerGas is not negative or too big
|
// Check that baseFeePerGas is not negative or too big
|
||||||
if params.BaseFeePerGas != nil && (params.BaseFeePerGas.Sign() == -1 || params.BaseFeePerGas.BitLen() > 256) {
|
if data.BaseFeePerGas != nil && (data.BaseFeePerGas.Sign() == -1 || data.BaseFeePerGas.BitLen() > 256) {
|
||||||
return nil, fmt.Errorf("invalid baseFeePerGas: %v", params.BaseFeePerGas)
|
return nil, fmt.Errorf("invalid baseFeePerGas: %v", data.BaseFeePerGas)
|
||||||
}
|
}
|
||||||
var blobHashes []common.Hash
|
var blobHashes = make([]common.Hash, 0, len(txs))
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
blobHashes = append(blobHashes, tx.BlobHashes()...)
|
blobHashes = append(blobHashes, tx.BlobHashes()...)
|
||||||
}
|
}
|
||||||
@@ -225,59 +252,73 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash,
|
|||||||
// ExecutableData before withdrawals are enabled by marshaling
|
// ExecutableData before withdrawals are enabled by marshaling
|
||||||
// Withdrawals as the json null value.
|
// Withdrawals as the json null value.
|
||||||
var withdrawalsRoot *common.Hash
|
var withdrawalsRoot *common.Hash
|
||||||
if params.Withdrawals != nil {
|
if data.Withdrawals != nil {
|
||||||
h := types.DeriveSha(types.Withdrawals(params.Withdrawals), trie.NewStackTrie(nil))
|
h := types.DeriveSha(types.Withdrawals(data.Withdrawals), trie.NewStackTrie(nil))
|
||||||
withdrawalsRoot = &h
|
withdrawalsRoot = &h
|
||||||
}
|
}
|
||||||
|
// Compute requestsHash if any requests are non-nil.
|
||||||
|
var (
|
||||||
|
requestsHash *common.Hash
|
||||||
|
requests types.Requests
|
||||||
|
)
|
||||||
|
if data.Deposits != nil {
|
||||||
|
requests = make(types.Requests, 0)
|
||||||
|
for _, d := range data.Deposits {
|
||||||
|
requests = append(requests, types.NewRequest(d))
|
||||||
|
}
|
||||||
|
h := types.DeriveSha(requests, trie.NewStackTrie(nil))
|
||||||
|
requestsHash = &h
|
||||||
|
}
|
||||||
header := &types.Header{
|
header := &types.Header{
|
||||||
ParentHash: params.ParentHash,
|
ParentHash: data.ParentHash,
|
||||||
UncleHash: types.EmptyUncleHash,
|
UncleHash: types.EmptyUncleHash,
|
||||||
Coinbase: params.FeeRecipient,
|
Coinbase: data.FeeRecipient,
|
||||||
Root: params.StateRoot,
|
Root: data.StateRoot,
|
||||||
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
|
TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
|
||||||
ReceiptHash: params.ReceiptsRoot,
|
ReceiptHash: data.ReceiptsRoot,
|
||||||
Bloom: types.BytesToBloom(params.LogsBloom),
|
Bloom: types.BytesToBloom(data.LogsBloom),
|
||||||
Difficulty: common.Big0,
|
Difficulty: common.Big0,
|
||||||
Number: new(big.Int).SetUint64(params.Number),
|
Number: new(big.Int).SetUint64(data.Number),
|
||||||
GasLimit: params.GasLimit,
|
GasLimit: data.GasLimit,
|
||||||
GasUsed: params.GasUsed,
|
GasUsed: data.GasUsed,
|
||||||
Time: params.Timestamp,
|
Time: data.Timestamp,
|
||||||
BaseFee: params.BaseFeePerGas,
|
BaseFee: data.BaseFeePerGas,
|
||||||
Extra: params.ExtraData,
|
Extra: data.ExtraData,
|
||||||
MixDigest: params.Random,
|
MixDigest: data.Random,
|
||||||
WithdrawalsHash: withdrawalsRoot,
|
WithdrawalsHash: withdrawalsRoot,
|
||||||
ExcessBlobGas: params.ExcessBlobGas,
|
ExcessBlobGas: data.ExcessBlobGas,
|
||||||
BlobGasUsed: params.BlobGasUsed,
|
BlobGasUsed: data.BlobGasUsed,
|
||||||
ParentBeaconRoot: beaconRoot,
|
ParentBeaconRoot: beaconRoot,
|
||||||
|
RequestsHash: requestsHash,
|
||||||
}
|
}
|
||||||
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals)
|
return types.NewBlockWithHeader(header).
|
||||||
if block.Hash() != params.BlockHash {
|
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals, Requests: requests}).
|
||||||
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash())
|
WithWitness(data.ExecutionWitness),
|
||||||
}
|
nil
|
||||||
return block, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockToExecutableData constructs the ExecutableData structure by filling the
|
// BlockToExecutableData constructs the ExecutableData structure by filling the
|
||||||
// fields from the given block. It assumes the given block is post-merge block.
|
// fields from the given block. It assumes the given block is post-merge block.
|
||||||
func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar) *ExecutionPayloadEnvelope {
|
func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar) *ExecutionPayloadEnvelope {
|
||||||
data := &ExecutableData{
|
data := &ExecutableData{
|
||||||
BlockHash: block.Hash(),
|
BlockHash: block.Hash(),
|
||||||
ParentHash: block.ParentHash(),
|
ParentHash: block.ParentHash(),
|
||||||
FeeRecipient: block.Coinbase(),
|
FeeRecipient: block.Coinbase(),
|
||||||
StateRoot: block.Root(),
|
StateRoot: block.Root(),
|
||||||
Number: block.NumberU64(),
|
Number: block.NumberU64(),
|
||||||
GasLimit: block.GasLimit(),
|
GasLimit: block.GasLimit(),
|
||||||
GasUsed: block.GasUsed(),
|
GasUsed: block.GasUsed(),
|
||||||
BaseFeePerGas: block.BaseFee(),
|
BaseFeePerGas: block.BaseFee(),
|
||||||
Timestamp: block.Time(),
|
Timestamp: block.Time(),
|
||||||
ReceiptsRoot: block.ReceiptHash(),
|
ReceiptsRoot: block.ReceiptHash(),
|
||||||
LogsBloom: block.Bloom().Bytes(),
|
LogsBloom: block.Bloom().Bytes(),
|
||||||
Transactions: encodeTransactions(block.Transactions()),
|
Transactions: encodeTransactions(block.Transactions()),
|
||||||
Random: block.MixDigest(),
|
Random: block.MixDigest(),
|
||||||
ExtraData: block.Extra(),
|
ExtraData: block.Extra(),
|
||||||
Withdrawals: block.Withdrawals(),
|
Withdrawals: block.Withdrawals(),
|
||||||
BlobGasUsed: block.BlobGasUsed(),
|
BlobGasUsed: block.BlobGasUsed(),
|
||||||
ExcessBlobGas: block.ExcessBlobGas(),
|
ExcessBlobGas: block.ExcessBlobGas(),
|
||||||
|
ExecutionWitness: block.ExecutionWitness(),
|
||||||
}
|
}
|
||||||
bundle := BlobsBundleV1{
|
bundle := BlobsBundleV1{
|
||||||
Commitments: make([]hexutil.Bytes, 0),
|
Commitments: make([]hexutil.Bytes, 0),
|
||||||
@@ -291,13 +332,30 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
|||||||
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
|
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setRequests(block.Requests(), data)
|
||||||
return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &bundle, Override: false}
|
return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &bundle, Override: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecutionPayloadBodyV1 is used in the response to GetPayloadBodiesByHashV1 and GetPayloadBodiesByRangeV1
|
// setRequests differentiates the different request types and
|
||||||
type ExecutionPayloadBodyV1 struct {
|
// assigns them to the associated fields in ExecutableData.
|
||||||
|
func setRequests(requests types.Requests, data *ExecutableData) {
|
||||||
|
if requests != nil {
|
||||||
|
// If requests is non-nil, it means deposits are available in block and we
|
||||||
|
// should return an empty slice instead of nil if there are no deposits.
|
||||||
|
data.Deposits = make(types.Deposits, 0)
|
||||||
|
}
|
||||||
|
for _, r := range requests {
|
||||||
|
if d, ok := r.Inner().(*types.Deposit); ok {
|
||||||
|
data.Deposits = append(data.Deposits, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecutionPayloadBody is used in the response to GetPayloadBodiesByHash and GetPayloadBodiesByRange
|
||||||
|
type ExecutionPayloadBody struct {
|
||||||
TransactionData []hexutil.Bytes `json:"transactions"`
|
TransactionData []hexutil.Bytes `json:"transactions"`
|
||||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||||
|
Deposits types.Deposits `json:"depositRequests"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client identifiers to support ClientVersionV1.
|
// Client identifiers to support ClientVersionV1.
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -120,8 +122,12 @@ func NewBeaconLightApi(url string, customHeaders map[string]string) *BeaconLight
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *BeaconLightApi) httpGet(path string) ([]byte, error) {
|
func (api *BeaconLightApi) httpGet(path string, params url.Values) ([]byte, error) {
|
||||||
req, err := http.NewRequest("GET", api.url+path, nil)
|
uri, err := api.buildURL(path, params)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("GET", uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -145,17 +151,16 @@ func (api *BeaconLightApi) httpGet(path string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *BeaconLightApi) httpGetf(format string, params ...any) ([]byte, error) {
|
|
||||||
return api.httpGet(fmt.Sprintf(format, params...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBestUpdatesAndCommittees fetches and validates LightClientUpdate for given
|
// GetBestUpdatesAndCommittees fetches and validates LightClientUpdate for given
|
||||||
// period and full serialized committee for the next period (committee root hash
|
// period and full serialized committee for the next period (committee root hash
|
||||||
// equals update.NextSyncCommitteeRoot).
|
// equals update.NextSyncCommitteeRoot).
|
||||||
// Note that the results are validated but the update signature should be verified
|
// Note that the results are validated but the update signature should be verified
|
||||||
// by the caller as its validity depends on the update chain.
|
// by the caller as its validity depends on the update chain.
|
||||||
func (api *BeaconLightApi) GetBestUpdatesAndCommittees(firstPeriod, count uint64) ([]*types.LightClientUpdate, []*types.SerializedSyncCommittee, error) {
|
func (api *BeaconLightApi) GetBestUpdatesAndCommittees(firstPeriod, count uint64) ([]*types.LightClientUpdate, []*types.SerializedSyncCommittee, error) {
|
||||||
resp, err := api.httpGetf("/eth/v1/beacon/light_client/updates?start_period=%d&count=%d", firstPeriod, count)
|
resp, err := api.httpGet("/eth/v1/beacon/light_client/updates", map[string][]string{
|
||||||
|
"start_period": {strconv.FormatUint(firstPeriod, 10)},
|
||||||
|
"count": {strconv.FormatUint(count, 10)},
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -192,7 +197,7 @@ func (api *BeaconLightApi) GetBestUpdatesAndCommittees(firstPeriod, count uint64
|
|||||||
// See data structure definition here:
|
// See data structure definition here:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientoptimisticupdate
|
||||||
func (api *BeaconLightApi) GetOptimisticUpdate() (types.OptimisticUpdate, error) {
|
func (api *BeaconLightApi) GetOptimisticUpdate() (types.OptimisticUpdate, error) {
|
||||||
resp, err := api.httpGet("/eth/v1/beacon/light_client/optimistic_update")
|
resp, err := api.httpGet("/eth/v1/beacon/light_client/optimistic_update", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.OptimisticUpdate{}, err
|
return types.OptimisticUpdate{}, err
|
||||||
}
|
}
|
||||||
@@ -245,7 +250,7 @@ func decodeOptimisticUpdate(enc []byte) (types.OptimisticUpdate, error) {
|
|||||||
// See data structure definition here:
|
// See data structure definition here:
|
||||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate
|
// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientfinalityupdate
|
||||||
func (api *BeaconLightApi) GetFinalityUpdate() (types.FinalityUpdate, error) {
|
func (api *BeaconLightApi) GetFinalityUpdate() (types.FinalityUpdate, error) {
|
||||||
resp, err := api.httpGet("/eth/v1/beacon/light_client/finality_update")
|
resp, err := api.httpGet("/eth/v1/beacon/light_client/finality_update", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.FinalityUpdate{}, err
|
return types.FinalityUpdate{}, err
|
||||||
}
|
}
|
||||||
@@ -311,7 +316,7 @@ func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, bool,
|
|||||||
} else {
|
} else {
|
||||||
blockId = blockRoot.Hex()
|
blockId = blockRoot.Hex()
|
||||||
}
|
}
|
||||||
resp, err := api.httpGetf("/eth/v1/beacon/headers/%s", blockId)
|
resp, err := api.httpGet(fmt.Sprintf("/eth/v1/beacon/headers/%s", blockId), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.Header{}, false, false, err
|
return types.Header{}, false, false, err
|
||||||
}
|
}
|
||||||
@@ -342,7 +347,7 @@ func (api *BeaconLightApi) GetHeader(blockRoot common.Hash) (types.Header, bool,
|
|||||||
|
|
||||||
// GetCheckpointData fetches and validates bootstrap data belonging to the given checkpoint.
|
// GetCheckpointData fetches and validates bootstrap data belonging to the given checkpoint.
|
||||||
func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types.BootstrapData, error) {
|
func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types.BootstrapData, error) {
|
||||||
resp, err := api.httpGetf("/eth/v1/beacon/light_client/bootstrap/0x%x", checkpointHash[:])
|
resp, err := api.httpGet(fmt.Sprintf("/eth/v1/beacon/light_client/bootstrap/0x%x", checkpointHash[:]), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -384,7 +389,7 @@ func (api *BeaconLightApi) GetCheckpointData(checkpointHash common.Hash) (*types
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api *BeaconLightApi) GetBeaconBlock(blockRoot common.Hash) (*types.BeaconBlock, error) {
|
func (api *BeaconLightApi) GetBeaconBlock(blockRoot common.Hash) (*types.BeaconBlock, error) {
|
||||||
resp, err := api.httpGetf("/eth/v2/beacon/blocks/0x%x", blockRoot)
|
resp, err := api.httpGet(fmt.Sprintf("/eth/v2/beacon/blocks/0x%x", blockRoot), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -494,9 +499,6 @@ func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func()
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
|
||||||
stream.Close()
|
|
||||||
|
|
||||||
case event, ok := <-stream.Events:
|
case event, ok := <-stream.Events:
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Trace("Event stream closed")
|
log.Trace("Event stream closed")
|
||||||
@@ -548,9 +550,13 @@ func (api *BeaconLightApi) StartHeadListener(listener HeadEventListener) func()
|
|||||||
// established. It can only return nil when the context is canceled.
|
// established. It can only return nil when the context is canceled.
|
||||||
func (api *BeaconLightApi) startEventStream(ctx context.Context, listener *HeadEventListener) *eventsource.Stream {
|
func (api *BeaconLightApi) startEventStream(ctx context.Context, listener *HeadEventListener) *eventsource.Stream {
|
||||||
for retry := true; retry; retry = ctxSleep(ctx, 5*time.Second) {
|
for retry := true; retry; retry = ctxSleep(ctx, 5*time.Second) {
|
||||||
path := "/eth/v1/events?topics=head&topics=light_client_finality_update&topics=light_client_optimistic_update"
|
|
||||||
log.Trace("Sending event subscription request")
|
log.Trace("Sending event subscription request")
|
||||||
req, err := http.NewRequestWithContext(ctx, "GET", api.url+path, nil)
|
uri, err := api.buildURL("/eth/v1/events", map[string][]string{"topics": {"head", "light_client_finality_update", "light_client_optimistic_update"}})
|
||||||
|
if err != nil {
|
||||||
|
listener.OnError(fmt.Errorf("error creating event subscription URL: %v", err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
listener.OnError(fmt.Errorf("error creating event subscription request: %v", err))
|
listener.OnError(fmt.Errorf("error creating event subscription request: %v", err))
|
||||||
continue
|
continue
|
||||||
@@ -579,3 +585,15 @@ func ctxSleep(ctx context.Context, timeout time.Duration) (ok bool) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *BeaconLightApi) buildURL(path string, params url.Values) (string, error) {
|
||||||
|
uri, err := url.Parse(api.url)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
uri = uri.JoinPath(path)
|
||||||
|
if params != nil {
|
||||||
|
uri.RawQuery = params.Encode()
|
||||||
|
}
|
||||||
|
return uri.String(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -186,10 +186,14 @@ func (s *serverWithTimeout) eventCallback(event Event) {
|
|||||||
// call will just do nothing
|
// call will just do nothing
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
delete(s.timeouts, id)
|
delete(s.timeouts, id)
|
||||||
s.childEventCb(event)
|
if s.childEventCb != nil {
|
||||||
|
s.childEventCb(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
s.childEventCb(event)
|
if s.childEventCb != nil {
|
||||||
|
s.childEventCb(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,25 +215,27 @@ func (s *serverWithTimeout) startTimeout(reqData RequestResponse) {
|
|||||||
delete(s.timeouts, id)
|
delete(s.timeouts, id)
|
||||||
childEventCb := s.childEventCb
|
childEventCb := s.childEventCb
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
childEventCb(Event{Type: EvFail, Data: reqData})
|
if childEventCb != nil {
|
||||||
|
childEventCb(Event{Type: EvFail, Data: reqData})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
childEventCb := s.childEventCb
|
childEventCb := s.childEventCb
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
childEventCb(Event{Type: EvTimeout, Data: reqData})
|
if childEventCb != nil {
|
||||||
|
childEventCb(Event{Type: EvTimeout, Data: reqData})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsubscribe stops all goroutines associated with the server.
|
// unsubscribe stops all goroutines associated with the server.
|
||||||
func (s *serverWithTimeout) unsubscribe() {
|
func (s *serverWithTimeout) unsubscribe() {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
|
||||||
|
|
||||||
for _, timer := range s.timeouts {
|
for _, timer := range s.timeouts {
|
||||||
if timer != nil {
|
if timer != nil {
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.childEventCb = nil
|
s.lock.Unlock()
|
||||||
s.parent.Unsubscribe()
|
s.parent.Unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,10 +334,10 @@ func (s *serverWithLimits) eventCallback(event Event) {
|
|||||||
}
|
}
|
||||||
childEventCb := s.childEventCb
|
childEventCb := s.childEventCb
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
if passEvent {
|
if passEvent && childEventCb != nil {
|
||||||
childEventCb(event)
|
childEventCb(event)
|
||||||
}
|
}
|
||||||
if sendCanRequestAgain {
|
if sendCanRequestAgain && childEventCb != nil {
|
||||||
childEventCb(Event{Type: EvCanRequestAgain})
|
childEventCb(Event{Type: EvCanRequestAgain})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,13 +353,12 @@ func (s *serverWithLimits) sendRequest(request Request) (reqId ID) {
|
|||||||
// unsubscribe stops all goroutines associated with the server.
|
// unsubscribe stops all goroutines associated with the server.
|
||||||
func (s *serverWithLimits) unsubscribe() {
|
func (s *serverWithLimits) unsubscribe() {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
|
||||||
|
|
||||||
if s.delayTimer != nil {
|
if s.delayTimer != nil {
|
||||||
s.delayTimer.Stop()
|
s.delayTimer.Stop()
|
||||||
s.delayTimer = nil
|
s.delayTimer = nil
|
||||||
}
|
}
|
||||||
s.childEventCb = nil
|
s.childEventCb = nil
|
||||||
|
s.lock.Unlock()
|
||||||
s.serverWithTimeout.unsubscribe()
|
s.serverWithTimeout.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,7 +388,7 @@ func (s *serverWithLimits) canRequestNow() bool {
|
|||||||
}
|
}
|
||||||
childEventCb := s.childEventCb
|
childEventCb := s.childEventCb
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
if sendCanRequestAgain {
|
if sendCanRequestAgain && childEventCb != nil {
|
||||||
childEventCb(Event{Type: EvCanRequestAgain})
|
childEventCb(Event{Type: EvCanRequestAgain})
|
||||||
}
|
}
|
||||||
return canRequest
|
return canRequest
|
||||||
@@ -415,7 +420,7 @@ func (s *serverWithLimits) delay(delay time.Duration) {
|
|||||||
}
|
}
|
||||||
childEventCb := s.childEventCb
|
childEventCb := s.childEventCb
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
if sendCanRequestAgain {
|
if sendCanRequestAgain && childEventCb != nil {
|
||||||
childEventCb(Event{Type: EvCanRequestAgain})
|
childEventCb(Event{Type: EvCanRequestAgain})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ func TestServerEvents(t *testing.T) {
|
|||||||
expEvent(EvFail)
|
expEvent(EvFail)
|
||||||
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
|
rs.eventCb(Event{Type: EvResponse, Data: RequestResponse{ID: 1, Request: testRequest, Response: testResponse}})
|
||||||
expEvent(nil)
|
expEvent(nil)
|
||||||
|
srv.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerParallel(t *testing.T) {
|
func TestServerParallel(t *testing.T) {
|
||||||
@@ -129,9 +130,7 @@ func TestServerEventRateLimit(t *testing.T) {
|
|||||||
srv := NewServer(rs, clock)
|
srv := NewServer(rs, clock)
|
||||||
var eventCount int
|
var eventCount int
|
||||||
srv.subscribe(func(event Event) {
|
srv.subscribe(func(event Event) {
|
||||||
if !event.IsRequestEvent() {
|
eventCount++
|
||||||
eventCount++
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
expEvents := func(send, expAllowed int) {
|
expEvents := func(send, expAllowed int) {
|
||||||
eventCount = 0
|
eventCount = 0
|
||||||
@@ -147,6 +146,30 @@ func TestServerEventRateLimit(t *testing.T) {
|
|||||||
expEvents(5, 1)
|
expEvents(5, 1)
|
||||||
clock.Run(maxServerEventRate * maxServerEventBuffer * 2)
|
clock.Run(maxServerEventRate * maxServerEventBuffer * 2)
|
||||||
expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
|
expEvents(maxServerEventBuffer+5, maxServerEventBuffer)
|
||||||
|
srv.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerUnsubscribe(t *testing.T) {
|
||||||
|
rs := &testRequestServer{}
|
||||||
|
clock := &mclock.Simulated{}
|
||||||
|
srv := NewServer(rs, clock)
|
||||||
|
var eventCount int
|
||||||
|
srv.subscribe(func(event Event) {
|
||||||
|
eventCount++
|
||||||
|
})
|
||||||
|
eventCb := rs.eventCb
|
||||||
|
eventCb(Event{Type: testEventType})
|
||||||
|
if eventCount != 1 {
|
||||||
|
t.Errorf("Server event callback not called before unsubscribe")
|
||||||
|
}
|
||||||
|
srv.unsubscribe()
|
||||||
|
if rs.eventCb != nil {
|
||||||
|
t.Errorf("Server event callback not removed after unsubscribe")
|
||||||
|
}
|
||||||
|
eventCb(Event{Type: testEventType})
|
||||||
|
if eventCount != 1 {
|
||||||
|
t.Errorf("Server event callback called after unsubscribe")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type testRequestServer struct {
|
type testRequestServer struct {
|
||||||
@@ -156,4 +179,4 @@ type testRequestServer struct {
|
|||||||
func (rs *testRequestServer) Name() string { return "" }
|
func (rs *testRequestServer) Name() string { return "" }
|
||||||
func (rs *testRequestServer) Subscribe(eventCb func(Event)) { rs.eventCb = eventCb }
|
func (rs *testRequestServer) Subscribe(eventCb func(Event)) { rs.eventCb = eventCb }
|
||||||
func (rs *testRequestServer) SendRequest(ID, Request) {}
|
func (rs *testRequestServer) SendRequest(ID, Request) {}
|
||||||
func (rs *testRequestServer) Unsubscribe() {}
|
func (rs *testRequestServer) Unsubscribe() { rs.eventCb = nil }
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ func TestValidatedHead(t *testing.T) {
|
|||||||
ts.ServerEvent(EvNewOptimisticUpdate, testServer3, testOptUpdate4)
|
ts.ServerEvent(EvNewOptimisticUpdate, testServer3, testOptUpdate4)
|
||||||
// finality should be requested from both servers
|
// finality should be requested from both servers
|
||||||
ts.Run(4, testServer1, ReqFinality{}, testServer3, ReqFinality{})
|
ts.Run(4, testServer1, ReqFinality{}, testServer3, ReqFinality{})
|
||||||
// future period annonced heads should be queued
|
// future period announced heads should be queued
|
||||||
ht.ExpValidated(t, 4, nil)
|
ht.ExpValidated(t, 4, nil)
|
||||||
|
|
||||||
chain.SetNextSyncPeriod(2)
|
chain.SetNextSyncPeriod(2)
|
||||||
|
|||||||
@@ -173,24 +173,24 @@ type TestCommitteeChain struct {
|
|||||||
init bool
|
init bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestCommitteeChain) CheckpointInit(bootstrap types.BootstrapData) error {
|
func (tc *TestCommitteeChain) CheckpointInit(bootstrap types.BootstrapData) error {
|
||||||
t.fsp, t.nsp, t.init = bootstrap.Header.SyncPeriod(), bootstrap.Header.SyncPeriod()+2, true
|
tc.fsp, tc.nsp, tc.init = bootstrap.Header.SyncPeriod(), bootstrap.Header.SyncPeriod()+2, true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestCommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
|
func (tc *TestCommitteeChain) InsertUpdate(update *types.LightClientUpdate, nextCommittee *types.SerializedSyncCommittee) error {
|
||||||
period := update.AttestedHeader.Header.SyncPeriod()
|
period := update.AttestedHeader.Header.SyncPeriod()
|
||||||
if period < t.fsp || period > t.nsp || !t.init {
|
if period < tc.fsp || period > tc.nsp || !tc.init {
|
||||||
return light.ErrInvalidPeriod
|
return light.ErrInvalidPeriod
|
||||||
}
|
}
|
||||||
if period == t.nsp {
|
if period == tc.nsp {
|
||||||
t.nsp++
|
tc.nsp++
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestCommitteeChain) NextSyncPeriod() (uint64, bool) {
|
func (tc *TestCommitteeChain) NextSyncPeriod() (uint64, bool) {
|
||||||
return t.nsp, t.init
|
return tc.nsp, tc.init
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *TestCommitteeChain) ExpInit(t *testing.T, ExpInit bool) {
|
func (tc *TestCommitteeChain) ExpInit(t *testing.T, ExpInit bool) {
|
||||||
@@ -199,8 +199,8 @@ func (tc *TestCommitteeChain) ExpInit(t *testing.T, ExpInit bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestCommitteeChain) SetNextSyncPeriod(nsp uint64) {
|
func (tc *TestCommitteeChain) SetNextSyncPeriod(nsp uint64) {
|
||||||
t.init, t.nsp = true, nsp
|
tc.init, tc.nsp = true, nsp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *TestCommitteeChain) ExpNextSyncPeriod(t *testing.T, expNsp uint64) {
|
func (tc *TestCommitteeChain) ExpNextSyncPeriod(t *testing.T, expNsp uint64) {
|
||||||
|
|||||||
@@ -201,6 +201,34 @@ func TestUpdateSyncDifferentHeads(t *testing.T) {
|
|||||||
chain.ExpNextSyncPeriod(t, 17)
|
chain.ExpNextSyncPeriod(t, 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRangeLock(t *testing.T) {
|
||||||
|
r := make(rangeLock)
|
||||||
|
|
||||||
|
// Lock from 0 to 99.
|
||||||
|
r.lock(0, 100, 1)
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
if v, ok := r[uint64(i)]; v <= 0 || !ok {
|
||||||
|
t.Fatalf("integer space: %d not locked", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock from 0 to 99.
|
||||||
|
r.lock(0, 100, -1)
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
if v, ok := r[uint64(i)]; v > 0 || ok {
|
||||||
|
t.Fatalf("integer space: %d is locked", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock from 0 to 99 then unlock from 10 to 59.
|
||||||
|
r.lock(0, 100, 1)
|
||||||
|
r.lock(10, 50, -1)
|
||||||
|
first, count := r.firstUnlocked(0, 100)
|
||||||
|
if first != 10 || count != 50 {
|
||||||
|
t.Fatalf("unexpected first: %d or count: %d", first, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testRespUpdate(request requestWithID) request.Response {
|
func testRespUpdate(request requestWithID) request.Response {
|
||||||
var resp RespUpdates
|
var resp RespUpdates
|
||||||
if request.request == nil {
|
if request.request == nil {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func BlockFromJSON(forkName string, data []byte) (*BeaconBlock, error) {
|
|||||||
case "capella":
|
case "capella":
|
||||||
obj = new(capella.BeaconBlock)
|
obj = new(capella.BeaconBlock)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported fork: " + forkName)
|
return nil, fmt.Errorf("unsupported fork: %s", forkName)
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, obj); err != nil {
|
if err := json.Unmarshal(data, obj); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, er
|
|||||||
case "deneb":
|
case "deneb":
|
||||||
obj = new(deneb.ExecutionPayloadHeader)
|
obj = new(deneb.ExecutionPayloadHeader)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported fork: " + forkName)
|
return nil, fmt.Errorf("unsupported fork: %s", forkName)
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, obj); err != nil {
|
if err := json.Unmarshal(data, obj); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -63,11 +63,9 @@ func convertPayload[T payloadType](payload T, parentRoot *zrntcommon.Root) (*typ
|
|||||||
panic("unsupported block type")
|
panic("unsupported block type")
|
||||||
}
|
}
|
||||||
|
|
||||||
block := types.NewBlockWithHeader(&header)
|
block := types.NewBlockWithHeader(&header).WithBody(types.Body{Transactions: transactions, Withdrawals: withdrawals})
|
||||||
block = block.WithBody(transactions, nil)
|
|
||||||
block = block.WithWithdrawals(withdrawals)
|
|
||||||
if hash := block.Hash(); hash != expectedHash {
|
if hash := block.Hash(); hash != expectedHash {
|
||||||
return nil, fmt.Errorf("Sanity check failed, payload hash does not match (expected %x, got %x)", expectedHash, hash)
|
return nil, fmt.Errorf("sanity check failed, payload hash does not match (expected %x, got %x)", expectedHash, hash)
|
||||||
}
|
}
|
||||||
return block, nil
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,61 +5,123 @@
|
|||||||
# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/
|
# https://github.com/ethereum/execution-spec-tests/releases/download/v2.1.0/
|
||||||
ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz
|
ca89c76851b0900bfcc3cbb9a26cbece1f3d7c64a3bed38723e914713290df6c fixtures_develop.tar.gz
|
||||||
|
|
||||||
# version:golang 1.22.2
|
# version:golang 1.23.1
|
||||||
# https://go.dev/dl/
|
# https://go.dev/dl/
|
||||||
374ea82b289ec738e968267cac59c7d5ff180f9492250254784b2044e90df5a9 go1.22.2.src.tar.gz
|
6ee44e298379d146a5e5aa6b1c5b5d5f5d0a3365eabdd70741e6e21340ec3b0d go1.23.1.src.tar.gz
|
||||||
33e7f63077b1c5bce4f1ecadd4d990cf229667c40bfb00686990c950911b7ab7 go1.22.2.darwin-amd64.tar.gz
|
f17f2791717c15728ec63213a014e244c35f9c8846fb29f5a1b63d0c0556f756 go1.23.1.aix-ppc64.tar.gz
|
||||||
660298be38648723e783ba0398e90431de1cb288c637880cdb124f39bd977f0d go1.22.2.darwin-arm64.tar.gz
|
dd9e772686ed908bcff94b6144322d4e2473a7dcd7c696b7e8b6d12f23c887fd go1.23.1.darwin-amd64.pkg
|
||||||
efc7162b0cad2f918ac566a923d4701feb29dc9c0ab625157d49b1cbcbba39da go1.22.2.freebsd-386.tar.gz
|
488d9e4ca3e3ed513ee4edd91bef3a2360c65fa6d6be59cf79640bf840130a58 go1.23.1.darwin-amd64.tar.gz
|
||||||
d753428296e6709527e291fd204700a587ffef2c0a472b21aebea11618245929 go1.22.2.freebsd-amd64.tar.gz
|
be34b488157ec69d94e26e1554558219a2c90789bcb7e3686965a7f9c8cfcbe7 go1.23.1.darwin-arm64.pkg
|
||||||
586d9eb7fe0489ab297ad80dd06414997df487c5cf536c490ffeaa8d8f1807a7 go1.22.2.linux-386.tar.gz
|
e223795ca340e285a760a6446ce57a74500b30e57469a4109961d36184d3c05a go1.23.1.darwin-arm64.tar.gz
|
||||||
5901c52b7a78002aeff14a21f93e0f064f74ce1360fce51c6ee68cd471216a17 go1.22.2.linux-amd64.tar.gz
|
6af626176923a6ae6c5de6dc1c864f38365793c0e4ecd0d6eab847bdc23953e5 go1.23.1.dragonfly-amd64.tar.gz
|
||||||
36e720b2d564980c162a48c7e97da2e407dfcc4239e1e58d98082dfa2486a0c1 go1.22.2.linux-arm64.tar.gz
|
cc957c1a019702e6cdc2e257202d42799011ebc1968b6c3bcd6b1965952607d5 go1.23.1.freebsd-386.tar.gz
|
||||||
9243dfafde06e1efe24d59df6701818e6786b4adfdf1191098050d6d023c5369 go1.22.2.linux-armv6l.tar.gz
|
a7d57781c50bb80886a8f04066791956d45aa3eea0f83070c5268b6223afb2ff go1.23.1.freebsd-amd64.tar.gz
|
||||||
251a8886c5113be6490bdbb955ddee98763b49c9b1bf4c8364c02d3b482dab00 go1.22.2.linux-ppc64le.tar.gz
|
c7b09f3fef456048e596db9bea746eb66796aeb82885622b0388feee18f36a3e go1.23.1.freebsd-arm.tar.gz
|
||||||
2b39019481c28c560d65e9811a478ae10e3ef765e0f59af362031d386a71bfef go1.22.2.linux-s390x.tar.gz
|
b05cd6a77995a0c8439d88df124811c725fb78b942d0b6dd1643529d7ba62f1f go1.23.1.freebsd-arm64.tar.gz
|
||||||
651753c06df037020ef4d162c5b273452e9ba976ed17ae39e66ef7ee89d8147e go1.22.2.windows-386.zip
|
56236ae70be1613f2915943b94f53c96be5bffc0719314078facd778a89bc57e go1.23.1.freebsd-riscv64.tar.gz
|
||||||
8e581cf330f49d3266e936521a2d8263679ef7e2fc2cbbceb85659122d883596 go1.22.2.windows-amd64.zip
|
8644c52df4e831202114fd67c9fcaf1f7233ad27bf945ac53fa7217cf1a0349f go1.23.1.illumos-amd64.tar.gz
|
||||||
ddfca5beb9a0c62254266c3090c2555d899bf3e7aa26243e7de3621108f06875 go1.22.2.windows-arm64.zip
|
cdee2f4e2efa001f7ee75c90f2efc310b63346cfbba7b549987e9139527c6b17 go1.23.1.linux-386.tar.gz
|
||||||
|
49bbb517cfa9eee677e1e7897f7cf9cfdbcf49e05f61984a2789136de359f9bd go1.23.1.linux-amd64.tar.gz
|
||||||
|
faec7f7f8ae53fda0f3d408f52182d942cc89ef5b7d3d9f23ff117437d4b2d2f go1.23.1.linux-arm64.tar.gz
|
||||||
|
6c7832c7dcd8fb6d4eb308f672a725393403c74ee7be1aeccd8a443015df99de go1.23.1.linux-armv6l.tar.gz
|
||||||
|
649ce3856ddc808c00b14a46232eab0bf95e7911cdf497010b17d76656f5ca4e go1.23.1.linux-loong64.tar.gz
|
||||||
|
201911048f234e5a0c51ec94b1a11d4e47062fee4398b1d2faa6c820dc026724 go1.23.1.linux-mips.tar.gz
|
||||||
|
2bce3743df463915e45d2612f9476ffb03d0b3750b1cb3879347de08715b5fc6 go1.23.1.linux-mips64.tar.gz
|
||||||
|
54e301f266e33431b0703136e0bbd4cf02461b1ecedd37b7cbd90cb862a98e5f go1.23.1.linux-mips64le.tar.gz
|
||||||
|
8efd495e93d17408c0803595cdc3bf13cb28e0f957aeabd9cc18245fb8e64019 go1.23.1.linux-mipsle.tar.gz
|
||||||
|
52bd68689095831ad9af7160844c23b28bb8d0acd268de7e300ff5f0662b7a07 go1.23.1.linux-ppc64.tar.gz
|
||||||
|
042888cae54b5fbfd9dd1e3b6bc4a5134879777fe6497fc4c62ec394b5ecf2da go1.23.1.linux-ppc64le.tar.gz
|
||||||
|
1a4a609f0391bea202d9095453cbfaf7368fa88a04c206bf9dd715a738664dc3 go1.23.1.linux-riscv64.tar.gz
|
||||||
|
47dc49ad45c45e192efa0df7dc7bc5403f5f2d15b5d0dc74ef3018154b616f4d go1.23.1.linux-s390x.tar.gz
|
||||||
|
fbfbd5efa6a5d581ea7f5e65015f927db0e52135cab057e43d39d5482da54b61 go1.23.1.netbsd-386.tar.gz
|
||||||
|
e96e1cc5cf36113ee6099d1a7306b22cd9c3f975a36bdff954c59f104f22b853 go1.23.1.netbsd-amd64.tar.gz
|
||||||
|
c394dfc06bfc276a591209a37e09cd39089ec9a9cc3db30b94814ce2e39eb1d4 go1.23.1.netbsd-arm.tar.gz
|
||||||
|
b3b35d64f32821a68b3e2994032dbefb81978f2ec3f218c7a770623b82d36b8e go1.23.1.netbsd-arm64.tar.gz
|
||||||
|
3c775c4c16c182e33c2c4ac090d9a247a93b3fb18a3df01d87d490f29599faff go1.23.1.openbsd-386.tar.gz
|
||||||
|
5edbe53b47c57b32707fd7154536fbe9eaa79053fea01650c93b54cdba13fc0f go1.23.1.openbsd-amd64.tar.gz
|
||||||
|
c30903dd8fa98b8aca8e9db0962ce9f55502aed93e0ef41e5ae148aaa0088de1 go1.23.1.openbsd-arm.tar.gz
|
||||||
|
12da183489e58f9c6b357bc1b626f85ed7d4220cab31a49d6a49e6ac6a718b67 go1.23.1.openbsd-arm64.tar.gz
|
||||||
|
9cc9aad37696a4a10c31dcec9e35a308de0b369dad354d54cf07406ac6fa7c6f go1.23.1.openbsd-ppc64.tar.gz
|
||||||
|
e1d740dda062ce5a276a0c3ed7d8b6353238bc8ff405f63e2e3480bfd26a5ec5 go1.23.1.openbsd-riscv64.tar.gz
|
||||||
|
da2a37f9987f01f096859230aa13ecc4ad2e7884465bce91004bc78c64435d65 go1.23.1.plan9-386.tar.gz
|
||||||
|
fd8fff8b0697d55c4a4d02a8dc998192b80a9dc2a057647373d6ff607cad29de go1.23.1.plan9-amd64.tar.gz
|
||||||
|
52efbc5804c1c86ba7868aa8ebbc31cc8c2a27b62a60fd57944970d48fc67525 go1.23.1.plan9-arm.tar.gz
|
||||||
|
f54205f21e2143f2ada1bf1c00ddf64590f5139d5c3fb77cc06175f0d8cc7567 go1.23.1.solaris-amd64.tar.gz
|
||||||
|
369a17f0cfd29e5c848e58ffe0d772da20abe334d1c7ca01dbcd55bb3db0b440 go1.23.1.windows-386.msi
|
||||||
|
ab866f47d7be56e6b1c67f1d529bf4c23331a339fb0785f435a0552d352cb257 go1.23.1.windows-386.zip
|
||||||
|
e99dac215ee437b9bb8f8b14bbfe0e8756882c1ed291f30818e8363bc9c047a5 go1.23.1.windows-amd64.msi
|
||||||
|
32dedf277c86610e380e1765593edb66876f00223df71690bd6be68ee17675c0 go1.23.1.windows-amd64.zip
|
||||||
|
23169c79dc6b54e0dffb25be6b67425ad9759392a58309bc057430a9bf4c8f6a go1.23.1.windows-arm.msi
|
||||||
|
1a57615a09f13534f88e9f2d7efd5743535d1a5719b19e520eef965a634f8efb go1.23.1.windows-arm.zip
|
||||||
|
313e1a543931ad8735b4df8969e00f5f4c2ef07be21f54015ede961a70263d35 go1.23.1.windows-arm64.msi
|
||||||
|
64ad0954d2c33f556fb1018d62de091254aa6e3a94f1c8a8b16af0d3701d194e go1.23.1.windows-arm64.zip
|
||||||
|
|
||||||
# version:golangci 1.55.2
|
# version:golangci 1.59.0
|
||||||
# https://github.com/golangci/golangci-lint/releases/
|
# https://github.com/golangci/golangci-lint/releases/
|
||||||
# https://github.com/golangci/golangci-lint/releases/download/v1.55.2/
|
# https://github.com/golangci/golangci-lint/releases/download/v1.59.0/
|
||||||
632e96e6d5294fbbe7b2c410a49c8fa01c60712a0af85a567de85bcc1623ea21 golangci-lint-1.55.2-darwin-amd64.tar.gz
|
418acf7e255ddc0783e97129c9b03d9311b77826a5311d425a01c708a86417e7 golangci-lint-1.59.0-darwin-amd64.tar.gz
|
||||||
234463f059249f82045824afdcdd5db5682d0593052f58f6a3039a0a1c3899f6 golangci-lint-1.55.2-darwin-arm64.tar.gz
|
5f6a1d95a6dd69f6e328eb56dd311a38e04cfab79a1305fbf4957f4e203f47b6 golangci-lint-1.59.0-darwin-arm64.tar.gz
|
||||||
2bdd105e2d4e003a9058c33a22bb191a1e0f30fa0790acca0d8fbffac1d6247c golangci-lint-1.55.2-freebsd-386.tar.gz
|
8899bf589185d49f747f3e5db9f0bde8a47245a100c64a3dd4d65e8e92cfc4f2 golangci-lint-1.59.0-freebsd-386.tar.gz
|
||||||
e75056e8b082386676ce23eba455cf893931a792c0d87e1e3743c0aec33c7fb5 golangci-lint-1.55.2-freebsd-amd64.tar.gz
|
658212f138d9df2ac89427e22115af34bf387c0871d70f2a25101718946a014f golangci-lint-1.59.0-freebsd-amd64.tar.gz
|
||||||
5789b933facaf6136bd23f1d50add67b79bbcf8dfdfc9069a37f729395940a66 golangci-lint-1.55.2-freebsd-armv6.tar.gz
|
4c6395ea40f314d3b6fa17d8997baab93464d5d1deeaab513155e625473bd03a golangci-lint-1.59.0-freebsd-armv6.tar.gz
|
||||||
7f21ab1008d05f32c954f99470fc86a83a059e530fe2add1d0b7d8ed4d8992a7 golangci-lint-1.55.2-freebsd-armv7.tar.gz
|
ff37da4fbaacdb6bbae70fdbdbb1ba932a859956f788c82822fa06bef5b7c6b3 golangci-lint-1.59.0-freebsd-armv7.tar.gz
|
||||||
33ab06139b9219a28251f10821da94423db30285cc2af97494cbb2a281927de9 golangci-lint-1.55.2-illumos-amd64.tar.gz
|
439739469ed2bda182b1ec276d40c40e02f195537f78e3672996741ad223d6b6 golangci-lint-1.59.0-illumos-amd64.tar.gz
|
||||||
57ce6f8ce3ad6ee45d7cc3d9a047545a851c2547637834a3fcb086c7b40b1e6b golangci-lint-1.55.2-linux-386.tar.gz
|
940801d46790e40d0a097d8fee34e2606f0ef148cd039654029b0b8750a15ed6 golangci-lint-1.59.0-linux-386.tar.gz
|
||||||
ca21c961a33be3bc15e4292dc40c98c8dcc5463a7b6768a3afc123761630c09c golangci-lint-1.55.2-linux-amd64.tar.gz
|
3b14a439f33c4fff83dbe0349950d984042b9a1feb6c62f82787b598fc3ab5f4 golangci-lint-1.59.0-linux-amd64.tar.gz
|
||||||
8eb0cee9b1dbf0eaa49871798c7f8a5b35f2960c52d776a5f31eb7d886b92746 golangci-lint-1.55.2-linux-arm64.tar.gz
|
c57e6c0b0fa03089a2611dceddd5bc5d206716cccdff8b149da8baac598719a1 golangci-lint-1.59.0-linux-arm64.tar.gz
|
||||||
3195f3e0f37d353fd5bd415cabcd4e263f5c29d3d0ffb176c26ff3d2c75eb3bb golangci-lint-1.55.2-linux-armv6.tar.gz
|
93149e2d3b25ac754df9a23172403d8aa6d021a7e0d9c090a12f51897f68c9a0 golangci-lint-1.59.0-linux-armv6.tar.gz
|
||||||
c823ee36eb1a719e171de1f2f5ca3068033dce8d9817232fd10ed71fd6650406 golangci-lint-1.55.2-linux-armv7.tar.gz
|
d10ac38239d9efee3ee87b55c96cdf3fa09e1a525babe3ffdaaf65ccc48cf3dc golangci-lint-1.59.0-linux-armv7.tar.gz
|
||||||
758a5d2a356dc494bd13ed4c0d4bf5a54a4dc91267ea5ecdd87b86c7ca0624e7 golangci-lint-1.55.2-linux-loong64.tar.gz
|
047338114b4f0d5f08f0fb9a397b03cc171916ed0960be7dfb355c2320cd5e9c golangci-lint-1.59.0-linux-loong64.tar.gz
|
||||||
2c7b9abdce7cae802a67d583cd7c6dca520bff6d0e17c8535a918e2f2b437aa0 golangci-lint-1.55.2-linux-mips64.tar.gz
|
5632df0f7f8fc03a80a266130faef0b5902d280cf60621f1b2bdc1aef6d97ee9 golangci-lint-1.59.0-linux-mips64.tar.gz
|
||||||
024e0a15b85352cc27271285526e16a4ab66d3e67afbbe446c9808c06cb8dbed golangci-lint-1.55.2-linux-mips64le.tar.gz
|
71dd638c82fa4439171e7126d2c7a32b5d103bfdef282cea40c83632cb3d1f4b golangci-lint-1.59.0-linux-mips64le.tar.gz
|
||||||
6b00f89ba5506c1de1efdd9fa17c54093013a294fefd8b9b31534db626a672ee golangci-lint-1.55.2-linux-ppc64le.tar.gz
|
6cf9ea0d34e91669948483f9ae7f07da319a879344373a1981099fbd890cde00 golangci-lint-1.59.0-linux-ppc64le.tar.gz
|
||||||
0faa0d047d9bf7b703ed3ea65b6117043c93504f9ca1de25ae929d3901c73d4a golangci-lint-1.55.2-linux-riscv64.tar.gz
|
af0205fa6fbab197cee613c359947711231739095d21b5c837086233b36ad971 golangci-lint-1.59.0-linux-riscv64.tar.gz
|
||||||
30dec9b22e7d5bb4e9d5ccea96da20f71cd7db3c8cf30b8ddc7cb9174c4d742a golangci-lint-1.55.2-linux-s390x.tar.gz
|
a9d2fb93f3c688ebccef94f5dc96c0b07c4d20bf6556cddebd8442159b0c80f6 golangci-lint-1.59.0-linux-s390x.tar.gz
|
||||||
5a0ede48f79ad707902fdb29be8cd2abd8302dc122b65ebae3fdfc86751c7698 golangci-lint-1.55.2-netbsd-386.tar.gz
|
68ab4c57a847b8ace9679887f2f8b2b6760e57ee29dcde8c3f40dd8bb2654fa2 golangci-lint-1.59.0-netbsd-386.tar.gz
|
||||||
95af20a2e617126dd5b08122ece7819101070e1582a961067ce8c41172f901ad golangci-lint-1.55.2-netbsd-amd64.tar.gz
|
d277b8b435c19406d00de4d509eadf5a024a5782878332e9a1b7c02bb76e87a7 golangci-lint-1.59.0-netbsd-amd64.tar.gz
|
||||||
94fb7dacb7527847cc95d7120904e19a2a0a81a0d50d61766c9e0251da72ab9d golangci-lint-1.55.2-netbsd-armv6.tar.gz
|
83211656be8dcfa1545af4f92894409f412d1f37566798cb9460a526593ad62c golangci-lint-1.59.0-netbsd-arm64.tar.gz
|
||||||
ca906bce5fee9619400e4a321c56476fe4a4efb6ac4fc989d340eb5563348873 golangci-lint-1.55.2-netbsd-armv7.tar.gz
|
6c6866d28bf79fa9817a0f7d2b050890ed109cae80bdb4dfa39536a7226da237 golangci-lint-1.59.0-netbsd-armv6.tar.gz
|
||||||
45b442f69fc8915c4500201c0247b7f3f69544dbc9165403a61f9095f2c57355 golangci-lint-1.55.2-windows-386.zip
|
11587566363bd03ca586b7df9776ccaed569fcd1f3489930ac02f9375b307503 golangci-lint-1.59.0-netbsd-armv7.tar.gz
|
||||||
f57d434d231d43417dfa631587522f8c1991220b43c8ffadb9c7bd279508bf81 golangci-lint-1.55.2-windows-amd64.zip
|
466181a8967bafa495e41494f93a0bec829c2cf715de874583b0460b3b8ae2b8 golangci-lint-1.59.0-windows-386.zip
|
||||||
fd7dc8f4c6829ee6fafb252a4d81d2155cd35da7833665cbb25d53ce7cecd990 golangci-lint-1.55.2-windows-arm64.zip
|
3317d8a87a99a49a0a1321d295c010790e6dbf43ee96b318f4b8bb23eae7a565 golangci-lint-1.59.0-windows-amd64.zip
|
||||||
1892c3c24f9e7ef44b02f6750c703864b6dc350129f3ec39510300007b2376f1 golangci-lint-1.55.2-windows-armv6.zip
|
b3af955c7fceac8220a36fc799e1b3f19d3b247d32f422caac5f9845df8f7316 golangci-lint-1.59.0-windows-arm64.zip
|
||||||
a5e68ae73d38748b5269fad36ac7575e3c162a5dc63ef58abdea03cc5da4522a golangci-lint-1.55.2-windows-armv7.zip
|
6f083c7d0c764e5a0e5bde46ee3e91ae357d80c194190fe1d9754392e9064c7e golangci-lint-1.59.0-windows-armv6.zip
|
||||||
|
3709b4dd425deadab27748778d08e03c0f804d7748f7dd5b6bb488d98aa031c7 golangci-lint-1.59.0-windows-armv7.zip
|
||||||
|
|
||||||
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
|
# This is the builder on PPA that will build Go itself (inception-y), don't modify!
|
||||||
#
|
#
|
||||||
# This version is fine to be old and full of security holes, we just use it
|
# This version is fine to be old and full of security holes, we just use it
|
||||||
# to build the latest Go. Don't change it. If it ever becomes insufficient,
|
# to build the latest Go. Don't change it.
|
||||||
# we need to switch over to a recursive builder to jump across supported
|
|
||||||
# versions.
|
|
||||||
#
|
#
|
||||||
# version:ppa-builder 1.19.6
|
# version:ppa-builder-1 1.19.6
|
||||||
# https://go.dev/dl/
|
# https://go.dev/dl/
|
||||||
d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz
|
d7f0013f82e6d7f862cc6cb5c8cdb48eef5f2e239b35baa97e2f1a7466043767 go1.19.6.src.tar.gz
|
||||||
|
|
||||||
|
# version:ppa-builder-2 1.21.9
|
||||||
|
# https://go.dev/dl/
|
||||||
|
58f0c5ced45a0012bce2ff7a9df03e128abcc8818ebabe5027bb92bafe20e421 go1.21.9.src.tar.gz
|
||||||
|
|
||||||
|
# version:protoc 27.1
|
||||||
|
# https://github.com/protocolbuffers/protobuf/releases/
|
||||||
|
# https://github.com/protocolbuffers/protobuf/releases/download/v27.1/
|
||||||
|
8809c2ec85368c6b6e9af161b6771a153aa92670a24adbe46dd34fa02a04df2f protoc-27.1-linux-aarch_64.zip
|
||||||
|
5d21979a6d27475e810b76b88863d1e784fa01ffb15e511a3ec5bd1924d89426 protoc-27.1-linux-ppcle_64.zip
|
||||||
|
84d8852750ed186dc4a057a1a86bcac409be5362d6af04770f42367fee6b7bc1 protoc-27.1-linux-s390_64.zip
|
||||||
|
2f028796ff5741691650e0eea290e61ff2f1c0d87f8d31fe45ef47fd967cef0c protoc-27.1-linux-x86_32.zip
|
||||||
|
8970e3d8bbd67d53768fe8c2e3971bdd71e51cfe2001ca06dacad17258a7dae3 protoc-27.1-linux-x86_64.zip
|
||||||
|
03b7af1bf469e7285dc51976ee5fa99412704dbd1c017105114852a37b165c12 protoc-27.1-osx-aarch_64.zip
|
||||||
|
f14d3973cf13283d07c520ed6f4c12405ad41b9efd18089a1c74897037d742b5 protoc-27.1-osx-universal_binary.zip
|
||||||
|
8520d944f3a3890fa296a3b3b0d4bb18337337e2526bbbf1b507eeea3c2a1ec4 protoc-27.1-osx-x86_64.zip
|
||||||
|
6263718ff96547b8392a079f6fdf02a4156f2e8d13cd51649a0d03fb7afa2de8 protoc-27.1-win32.zip
|
||||||
|
da531c51ccd1290d8d34821f0ce4e219c7fbaa6f9825f5a3fb092a9d03fe6206 protoc-27.1-win64.zip
|
||||||
|
|
||||||
|
# version:protoc-gen-go 1.34.2
|
||||||
|
# https://github.com/protocolbuffers/protobuf-go/releases/
|
||||||
|
# https://github.com/protocolbuffers/protobuf-go/releases/download/v1.34.2/
|
||||||
|
9b48d8f90add02e8e94e14962fed74e7ce2b2d6bda4dd42f1f4fbccf0f766f1a protoc-gen-go.v1.34.2.darwin.amd64.tar.gz
|
||||||
|
17aca7f948dbb624049030cf841e35895cf34183ba006e721247fdeb95ff2780 protoc-gen-go.v1.34.2.darwin.arm64.tar.gz
|
||||||
|
a191849433fd489f1d44f37788d762658f3f5fb225f3a85d4ce6ba32666703ed protoc-gen-go.v1.34.2.linux.386.tar.gz
|
||||||
|
b87bc134dee55576a842141bf0ed27761c635d746780fce5dee038c6dd16554f protoc-gen-go.v1.34.2.linux.amd64.tar.gz
|
||||||
|
63d400167e75ab9f6690688f6fdc6a9455aa20bc1faa71e32149dbd322f7f198 protoc-gen-go.v1.34.2.linux.arm64.tar.gz
|
||||||
|
56e7675816db6e62be4f833a51544d5716b8420c462515579e05ca8444ab06ed protoc-gen-go.v1.34.2.windows.386.zip
|
||||||
|
abafd39612177dd4e9a65207cadd5374a9352d8611e8e040f8462fcfa3010daf protoc-gen-go.v1.34.2.windows.amd64.zip
|
||||||
|
|||||||
479
build/ci.go
479
build/ci.go
@@ -39,16 +39,17 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -117,23 +118,13 @@ var (
|
|||||||
debEthereum,
|
debEthereum,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distros for which packages are created.
|
// Distros for which packages are created
|
||||||
// Note: vivid is unsupported because there is no golang-1.6 package for it.
|
debDistros = []string{
|
||||||
// Note: the following Ubuntu releases have been officially deprecated on Launchpad:
|
"xenial", // 16.04, EOL: 04/2026
|
||||||
// wily, yakkety, zesty, artful, cosmic, disco, eoan, groovy, hirsuite, impish,
|
"bionic", // 18.04, EOL: 04/2028
|
||||||
// kinetic, lunar
|
"focal", // 20.04, EOL: 04/2030
|
||||||
debDistroGoBoots = map[string]string{
|
"jammy", // 22.04, EOL: 04/2032
|
||||||
"trusty": "golang-1.11", // 14.04, EOL: 04/2024
|
"noble", // 24.04, EOL: 04/2034
|
||||||
"xenial": "golang-go", // 16.04, EOL: 04/2026
|
|
||||||
"bionic": "golang-go", // 18.04, EOL: 04/2028
|
|
||||||
"focal": "golang-go", // 20.04, EOL: 04/2030
|
|
||||||
"jammy": "golang-go", // 22.04, EOL: 04/2032
|
|
||||||
"mantic": "golang-go", // 23.10, EOL: 07/2024
|
|
||||||
}
|
|
||||||
|
|
||||||
debGoBootPaths = map[string]string{
|
|
||||||
"golang-1.11": "/usr/lib/go-1.11",
|
|
||||||
"golang-go": "/usr/lib/go",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is where the tests should be unpacked.
|
// This is where the tests should be unpacked.
|
||||||
@@ -167,8 +158,8 @@ func main() {
|
|||||||
doLint(os.Args[2:])
|
doLint(os.Args[2:])
|
||||||
case "archive":
|
case "archive":
|
||||||
doArchive(os.Args[2:])
|
doArchive(os.Args[2:])
|
||||||
case "docker":
|
case "dockerx":
|
||||||
doDocker(os.Args[2:])
|
doDockerBuildx(os.Args[2:])
|
||||||
case "debsrc":
|
case "debsrc":
|
||||||
doDebianSource(os.Args[2:])
|
doDebianSource(os.Args[2:])
|
||||||
case "nsis":
|
case "nsis":
|
||||||
@@ -177,6 +168,8 @@ func main() {
|
|||||||
doPurge(os.Args[2:])
|
doPurge(os.Args[2:])
|
||||||
case "sanitycheck":
|
case "sanitycheck":
|
||||||
doSanityCheck()
|
doSanityCheck()
|
||||||
|
case "generate":
|
||||||
|
doGenerate()
|
||||||
default:
|
default:
|
||||||
log.Fatal("unknown command ", os.Args[1])
|
log.Fatal("unknown command ", os.Args[1])
|
||||||
}
|
}
|
||||||
@@ -243,6 +236,10 @@ func doInstall(cmdline []string) {
|
|||||||
// buildFlags returns the go tool flags for building.
|
// buildFlags returns the go tool flags for building.
|
||||||
func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (flags []string) {
|
func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (flags []string) {
|
||||||
var ld []string
|
var ld []string
|
||||||
|
// See https://github.com/golang/go/issues/33772#issuecomment-528176001
|
||||||
|
// We need to set --buildid to the linker here, and also pass --build-id to the
|
||||||
|
// cgo-linker further down.
|
||||||
|
ld = append(ld, "--buildid=none")
|
||||||
if env.Commit != "" {
|
if env.Commit != "" {
|
||||||
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitCommit="+env.Commit)
|
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitCommit="+env.Commit)
|
||||||
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitDate="+env.Date)
|
ld = append(ld, "-X", "github.com/ethereum/go-ethereum/internal/version.gitDate="+env.Date)
|
||||||
@@ -255,7 +252,11 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (
|
|||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
// Enforce the stacksize to 8M, which is the case on most platforms apart from
|
// Enforce the stacksize to 8M, which is the case on most platforms apart from
|
||||||
// alpine Linux.
|
// alpine Linux.
|
||||||
extld := []string{"-Wl,-z,stack-size=0x800000"}
|
// See https://sourceware.org/binutils/docs-2.23.1/ld/Options.html#Options
|
||||||
|
// regarding the options --build-id=none and --strip-all. It is needed for
|
||||||
|
// reproducible builds; removing references to temporary files in C-land, and
|
||||||
|
// making build-id reproducably absent.
|
||||||
|
extld := []string{"-Wl,-z,stack-size=0x800000,--build-id=none,--strip-all"}
|
||||||
if staticLinking {
|
if staticLinking {
|
||||||
extld = append(extld, "-static")
|
extld = append(extld, "-static")
|
||||||
// Under static linking, use of certain glibc features must be
|
// Under static linking, use of certain glibc features must be
|
||||||
@@ -302,7 +303,7 @@ func doTest(cmdline []string) {
|
|||||||
gotest := tc.Go("test")
|
gotest := tc.Go("test")
|
||||||
|
|
||||||
// CI needs a bit more time for the statetests (default 10m).
|
// CI needs a bit more time for the statetests (default 10m).
|
||||||
gotest.Args = append(gotest.Args, "-timeout=20m")
|
gotest.Args = append(gotest.Args, "-timeout=30m")
|
||||||
|
|
||||||
// Enable CKZG backend in CI.
|
// Enable CKZG backend in CI.
|
||||||
gotest.Args = append(gotest.Args, "-tags=ckzg")
|
gotest.Args = append(gotest.Args, "-tags=ckzg")
|
||||||
@@ -353,6 +354,130 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string {
|
|||||||
return filepath.Join(cachedir, base)
|
return filepath.Join(cachedir, base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hashAllSourceFiles iterates all files under the top-level project directory
|
||||||
|
// computing the hash of each file (excluding files within the tests
|
||||||
|
// subrepo)
|
||||||
|
func hashAllSourceFiles() (map[string]common.Hash, error) {
|
||||||
|
res := make(map[string]common.Hash)
|
||||||
|
err := filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error {
|
||||||
|
if strings.HasPrefix(path, filepath.FromSlash("tests/testdata")) {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
if !d.Type().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// open the file and hash it
|
||||||
|
f, err := os.OpenFile(path, os.O_RDONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hasher := sha256.New()
|
||||||
|
if _, err := io.Copy(hasher, f); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res[path] = common.Hash(hasher.Sum(nil))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// hashSourceFiles iterates the provided set of filepaths (relative to the top-level geth project directory)
|
||||||
|
// computing the hash of each file.
|
||||||
|
func hashSourceFiles(files []string) (map[string]common.Hash, error) {
|
||||||
|
res := make(map[string]common.Hash)
|
||||||
|
for _, filePath := range files {
|
||||||
|
f, err := os.OpenFile(filePath, os.O_RDONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasher := sha256.New()
|
||||||
|
if _, err := io.Copy(hasher, f); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res[filePath] = common.Hash(hasher.Sum(nil))
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// compareHashedFilesets compares two maps (key is relative file path to top-level geth directory, value is its hash)
|
||||||
|
// and returns the list of file paths whose hashes differed.
|
||||||
|
func compareHashedFilesets(preHashes map[string]common.Hash, postHashes map[string]common.Hash) []string {
|
||||||
|
updates := []string{}
|
||||||
|
for path, postHash := range postHashes {
|
||||||
|
preHash, ok := preHashes[path]
|
||||||
|
if !ok || preHash != postHash {
|
||||||
|
updates = append(updates, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updates
|
||||||
|
}
|
||||||
|
|
||||||
|
func doGoModTidy() {
|
||||||
|
targetFiles := []string{"go.mod", "go.sum"}
|
||||||
|
preHashes, err := hashSourceFiles(targetFiles)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to hash go.mod/go.sum", "err", err)
|
||||||
|
}
|
||||||
|
tc := new(build.GoToolchain)
|
||||||
|
c := tc.Go("mod", "tidy")
|
||||||
|
build.MustRun(c)
|
||||||
|
postHashes, err := hashSourceFiles(targetFiles)
|
||||||
|
updates := compareHashedFilesets(preHashes, postHashes)
|
||||||
|
for _, updatedFile := range updates {
|
||||||
|
fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile)
|
||||||
|
}
|
||||||
|
if len(updates) != 0 {
|
||||||
|
log.Fatal("go.sum and/or go.mod were updated by running 'go mod tidy'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// doGenerate ensures that re-generating generated files does not cause
|
||||||
|
// any mutations in the source file tree: i.e. all generated files were
|
||||||
|
// updated and committed. Any stale generated files are updated.
|
||||||
|
func doGenerate() {
|
||||||
|
var (
|
||||||
|
tc = new(build.GoToolchain)
|
||||||
|
cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.")
|
||||||
|
verify = flag.Bool("verify", false, "check whether any files are changed by go generate")
|
||||||
|
)
|
||||||
|
|
||||||
|
protocPath := downloadProtoc(*cachedir)
|
||||||
|
protocGenGoPath := downloadProtocGenGo(*cachedir)
|
||||||
|
|
||||||
|
var preHashes map[string]common.Hash
|
||||||
|
if *verify {
|
||||||
|
var err error
|
||||||
|
preHashes, err = hashAllSourceFiles()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to compute map of source hashes", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := tc.Go("generate", "./...")
|
||||||
|
pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")}
|
||||||
|
c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator)))
|
||||||
|
build.MustRun(c)
|
||||||
|
|
||||||
|
if !*verify {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Check if files were changed.
|
||||||
|
postHashes, err := hashAllSourceFiles()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error computing source tree file hashes", "err", err)
|
||||||
|
}
|
||||||
|
updates := compareHashedFilesets(preHashes, postHashes)
|
||||||
|
for _, updatedFile := range updates {
|
||||||
|
fmt.Fprintf(os.Stderr, "changed file %s\n", updatedFile)
|
||||||
|
}
|
||||||
|
if len(updates) != 0 {
|
||||||
|
log.Fatal("One or more generated files were updated by running 'go generate ./...'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// doLint runs golangci-lint on requested packages.
|
// doLint runs golangci-lint on requested packages.
|
||||||
func doLint(cmdline []string) {
|
func doLint(cmdline []string) {
|
||||||
var (
|
var (
|
||||||
@@ -367,6 +492,8 @@ func doLint(cmdline []string) {
|
|||||||
linter := downloadLinter(*cachedir)
|
linter := downloadLinter(*cachedir)
|
||||||
lflags := []string{"run", "--config", ".golangci.yml"}
|
lflags := []string{"run", "--config", ".golangci.yml"}
|
||||||
build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
|
build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
|
||||||
|
|
||||||
|
doGoModTidy()
|
||||||
fmt.Println("You have achieved perfection.")
|
fmt.Println("You have achieved perfection.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,6 +525,96 @@ func downloadLinter(cachedir string) string {
|
|||||||
return filepath.Join(cachedir, base, "golangci-lint")
|
return filepath.Join(cachedir, base, "golangci-lint")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// protocArchiveBaseName returns the name of the protoc archive file for
|
||||||
|
// the current system, stripped of version and file suffix.
|
||||||
|
func protocArchiveBaseName() (string, error) {
|
||||||
|
switch runtime.GOOS + "-" + runtime.GOARCH {
|
||||||
|
case "windows-amd64":
|
||||||
|
return "win64", nil
|
||||||
|
case "windows-386":
|
||||||
|
return "win32", nil
|
||||||
|
case "linux-arm64":
|
||||||
|
return "linux-aarch_64", nil
|
||||||
|
case "linux-386":
|
||||||
|
return "linux-x86_32", nil
|
||||||
|
case "linux-amd64":
|
||||||
|
return "linux-x86_64", nil
|
||||||
|
case "darwin-arm64":
|
||||||
|
return "osx-aarch_64", nil
|
||||||
|
case "darwin-amd64":
|
||||||
|
return "osx-x86_64", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("no prebuilt release of protoc available for this system (os: %s, arch: %s)", runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// downloadProtocGenGo downloads protoc-gen-go, which is used by protoc
|
||||||
|
// in the generate command. It returns the full path of the directory
|
||||||
|
// containing the 'protoc-gen-go' executable.
|
||||||
|
func downloadProtocGenGo(cachedir string) string {
|
||||||
|
csdb := build.MustLoadChecksums("build/checksums.txt")
|
||||||
|
version, err := build.Version(csdb, "protoc-gen-go")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
baseName := fmt.Sprintf("protoc-gen-go.v%s.%s.%s", version, runtime.GOOS, runtime.GOARCH)
|
||||||
|
archiveName := baseName
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
archiveName += ".zip"
|
||||||
|
} else {
|
||||||
|
archiveName += ".tar.gz"
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf-go/releases/download/v%s/%s", version, archiveName)
|
||||||
|
|
||||||
|
archivePath := path.Join(cachedir, archiveName)
|
||||||
|
if err := csdb.DownloadFile(url, archivePath); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
extractDest := filepath.Join(cachedir, baseName)
|
||||||
|
if err := build.ExtractArchive(archivePath, extractDest); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
extractDest, err = filepath.Abs(extractDest)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error resolving absolute path for protoc", "err", err)
|
||||||
|
}
|
||||||
|
return extractDest
|
||||||
|
}
|
||||||
|
|
||||||
|
// downloadProtoc downloads the prebuilt protoc binary used to lint generated
|
||||||
|
// files as a CI step. It returns the full path to the directory containing
|
||||||
|
// the protoc executable.
|
||||||
|
func downloadProtoc(cachedir string) string {
|
||||||
|
csdb := build.MustLoadChecksums("build/checksums.txt")
|
||||||
|
version, err := build.Version(csdb, "protoc")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
baseName, err := protocArchiveBaseName()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName := fmt.Sprintf("protoc-%s-%s", version, baseName)
|
||||||
|
archiveFileName := fileName + ".zip"
|
||||||
|
url := fmt.Sprintf("https://github.com/protocolbuffers/protobuf/releases/download/v%s/%s", version, archiveFileName)
|
||||||
|
archivePath := filepath.Join(cachedir, archiveFileName)
|
||||||
|
|
||||||
|
if err := csdb.DownloadFile(url, archivePath); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
extractDest := filepath.Join(cachedir, fileName)
|
||||||
|
if err := build.ExtractArchive(archivePath, extractDest); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
extractDest, err = filepath.Abs(extractDest)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error resolving absolute path for protoc", "err", err)
|
||||||
|
}
|
||||||
|
return extractDest
|
||||||
|
}
|
||||||
|
|
||||||
// Release Packaging
|
// Release Packaging
|
||||||
func doArchive(cmdline []string) {
|
func doArchive(cmdline []string) {
|
||||||
var (
|
var (
|
||||||
@@ -505,10 +722,9 @@ func maybeSkipArchive(env build.Environment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Builds the docker images and optionally uploads them to Docker Hub.
|
// Builds the docker images and optionally uploads them to Docker Hub.
|
||||||
func doDocker(cmdline []string) {
|
func doDockerBuildx(cmdline []string) {
|
||||||
var (
|
var (
|
||||||
image = flag.Bool("image", false, `Whether to build and push an arch specific docker image`)
|
platform = flag.String("platform", "", `Push a multi-arch docker image for the specified architectures (usually "linux/amd64,linux/arm64")`)
|
||||||
manifest = flag.String("manifest", "", `Push a multi-arch docker image for the specified architectures (usually "amd64,arm64")`)
|
|
||||||
upload = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`)
|
upload = flag.String("upload", "", `Where to upload the docker image (usually "ethereum/client-go")`)
|
||||||
)
|
)
|
||||||
flag.CommandLine.Parse(cmdline)
|
flag.CommandLine.Parse(cmdline)
|
||||||
@@ -543,129 +759,26 @@ func doDocker(cmdline []string) {
|
|||||||
case strings.HasPrefix(env.Tag, "v1."):
|
case strings.HasPrefix(env.Tag, "v1."):
|
||||||
tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), "v" + params.Version}
|
tags = []string{"stable", fmt.Sprintf("release-1.%d", params.VersionMinor), "v" + params.Version}
|
||||||
}
|
}
|
||||||
// If architecture specific image builds are requested, build and push them
|
// Need to create a mult-arch builder
|
||||||
if *image {
|
build.MustRunCommand("docker", "buildx", "create", "--use", "--name", "multi-arch-builder", "--platform", *platform)
|
||||||
build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:TAG", *upload), ".")
|
|
||||||
build.MustRunCommand("docker", "build", "--build-arg", "COMMIT="+env.Commit, "--build-arg", "VERSION="+params.VersionWithMeta, "--build-arg", "BUILDNUM="+env.Buildnum, "--tag", fmt.Sprintf("%s:alltools-TAG", *upload), "-f", "Dockerfile.alltools", ".")
|
|
||||||
|
|
||||||
// Tag and upload the images to Docker Hub
|
for _, spec := range []struct {
|
||||||
for _, tag := range tags {
|
file string
|
||||||
gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, runtime.GOARCH)
|
base string
|
||||||
toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, runtime.GOARCH)
|
}{
|
||||||
|
{file: "Dockerfile", base: fmt.Sprintf("%s:", *upload)},
|
||||||
// If the image already exists (non version tag), check the build
|
{file: "Dockerfile.alltools", base: fmt.Sprintf("%s:alltools-", *upload)},
|
||||||
// number to prevent overwriting a newer commit if concurrent builds
|
} {
|
||||||
// are running. This is still a tiny bit racey if two published are
|
for _, tag := range tags { // latest, stable etc
|
||||||
// done at the same time, but that's extremely unlikely even on the
|
gethImage := fmt.Sprintf("%s%s", spec.base, tag)
|
||||||
// master branch.
|
build.MustRunCommand("docker", "buildx", "build",
|
||||||
for _, img := range []string{gethImage, toolImage} {
|
"--build-arg", "COMMIT="+env.Commit,
|
||||||
if exec.Command("docker", "pull", img).Run() != nil {
|
"--build-arg", "VERSION="+params.VersionWithMeta,
|
||||||
continue // Generally the only failure is a missing image, which is good
|
"--build-arg", "BUILDNUM="+env.Buildnum,
|
||||||
}
|
"--tag", gethImage,
|
||||||
buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput()
|
"--platform", *platform,
|
||||||
if err != nil {
|
"--push",
|
||||||
log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum))
|
"--file", spec.file, ".")
|
||||||
}
|
|
||||||
buildnum = bytes.TrimSpace(buildnum)
|
|
||||||
|
|
||||||
if len(buildnum) > 0 && len(env.Buildnum) > 0 {
|
|
||||||
oldnum, err := strconv.Atoi(string(buildnum))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to parse old image build number: %v", err)
|
|
||||||
}
|
|
||||||
newnum, err := strconv.Atoi(env.Buildnum)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to parse current build number: %v", err)
|
|
||||||
}
|
|
||||||
if oldnum > newnum {
|
|
||||||
log.Fatalf("Current build number %d not newer than existing %d", newnum, oldnum)
|
|
||||||
} else {
|
|
||||||
log.Printf("Updating %s from build %d to %d", img, oldnum, newnum)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:TAG", *upload), gethImage)
|
|
||||||
build.MustRunCommand("docker", "image", "tag", fmt.Sprintf("%s:alltools-TAG", *upload), toolImage)
|
|
||||||
build.MustRunCommand("docker", "push", gethImage)
|
|
||||||
build.MustRunCommand("docker", "push", toolImage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If multi-arch image manifest push is requested, assemble it
|
|
||||||
if len(*manifest) != 0 {
|
|
||||||
// Since different architectures are pushed by different builders, wait
|
|
||||||
// until all required images are updated.
|
|
||||||
var mismatch bool
|
|
||||||
for i := 0; i < 2; i++ { // 2 attempts, second is race check
|
|
||||||
mismatch = false // hope there's no mismatch now
|
|
||||||
|
|
||||||
for _, tag := range tags {
|
|
||||||
for _, arch := range strings.Split(*manifest, ",") {
|
|
||||||
gethImage := fmt.Sprintf("%s:%s-%s", *upload, tag, arch)
|
|
||||||
toolImage := fmt.Sprintf("%s:alltools-%s-%s", *upload, tag, arch)
|
|
||||||
|
|
||||||
for _, img := range []string{gethImage, toolImage} {
|
|
||||||
if out, err := exec.Command("docker", "pull", img).CombinedOutput(); err != nil {
|
|
||||||
log.Printf("Required image %s unavailable: %v\nOutput: %s", img, err, out)
|
|
||||||
mismatch = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
buildnum, err := exec.Command("docker", "inspect", "--format", "{{index .Config.Labels \"buildnum\"}}", img).CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to inspect container: %v\nOutput: %s", err, string(buildnum))
|
|
||||||
}
|
|
||||||
buildnum = bytes.TrimSpace(buildnum)
|
|
||||||
|
|
||||||
if string(buildnum) != env.Buildnum {
|
|
||||||
log.Printf("Build number mismatch on %s: want %s, have %s", img, env.Buildnum, buildnum)
|
|
||||||
mismatch = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mismatch {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mismatch {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if mismatch {
|
|
||||||
// Build numbers mismatching, retry in a short time to
|
|
||||||
// avoid concurrent fails in both publisher images. If
|
|
||||||
// however the retry failed too, it means the concurrent
|
|
||||||
// builder is still crunching, let that do the publish.
|
|
||||||
if i == 0 {
|
|
||||||
time.Sleep(30 * time.Second)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if mismatch {
|
|
||||||
log.Println("Relinquishing publish to other builder")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Assemble and push the Geth manifest image
|
|
||||||
for _, tag := range tags {
|
|
||||||
gethImage := fmt.Sprintf("%s:%s", *upload, tag)
|
|
||||||
|
|
||||||
var gethSubImages []string
|
|
||||||
for _, arch := range strings.Split(*manifest, ",") {
|
|
||||||
gethSubImages = append(gethSubImages, gethImage+"-"+arch)
|
|
||||||
}
|
|
||||||
build.MustRunCommand("docker", append([]string{"manifest", "create", gethImage}, gethSubImages...)...)
|
|
||||||
build.MustRunCommand("docker", "manifest", "push", gethImage)
|
|
||||||
}
|
|
||||||
// Assemble and push the alltools manifest image
|
|
||||||
for _, tag := range tags {
|
|
||||||
toolImage := fmt.Sprintf("%s:alltools-%s", *upload, tag)
|
|
||||||
|
|
||||||
var toolSubImages []string
|
|
||||||
for _, arch := range strings.Split(*manifest, ",") {
|
|
||||||
toolSubImages = append(toolSubImages, toolImage+"-"+arch)
|
|
||||||
}
|
|
||||||
build.MustRunCommand("docker", append([]string{"manifest", "create", toolImage}, toolSubImages...)...)
|
|
||||||
build.MustRunCommand("docker", "manifest", "push", toolImage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -694,8 +807,8 @@ func doDebianSource(cmdline []string) {
|
|||||||
}
|
}
|
||||||
// Download and verify the Go source packages.
|
// Download and verify the Go source packages.
|
||||||
var (
|
var (
|
||||||
gobootbundle = downloadGoBootstrapSources(*cachedir)
|
gobootbundles = downloadGoBootstrapSources(*cachedir)
|
||||||
gobundle = downloadGoSources(*cachedir)
|
gobundle = downloadGoSources(*cachedir)
|
||||||
)
|
)
|
||||||
// Download all the dependencies needed to build the sources and run the ci script
|
// Download all the dependencies needed to build the sources and run the ci script
|
||||||
srcdepfetch := tc.Go("mod", "download")
|
srcdepfetch := tc.Go("mod", "download")
|
||||||
@@ -708,17 +821,19 @@ func doDebianSource(cmdline []string) {
|
|||||||
|
|
||||||
// Create Debian packages and upload them.
|
// Create Debian packages and upload them.
|
||||||
for _, pkg := range debPackages {
|
for _, pkg := range debPackages {
|
||||||
for distro, goboot := range debDistroGoBoots {
|
for _, distro := range debDistros {
|
||||||
// Prepare the debian package with the go-ethereum sources.
|
// Prepare the debian package with the go-ethereum sources.
|
||||||
meta := newDebMetadata(distro, goboot, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables)
|
meta := newDebMetadata(distro, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables)
|
||||||
pkgdir := stageDebianSource(*workdir, meta)
|
pkgdir := stageDebianSource(*workdir, meta)
|
||||||
|
|
||||||
// Add bootstrapper Go source code
|
// Add bootstrapper Go source code
|
||||||
if err := build.ExtractArchive(gobootbundle, pkgdir); err != nil {
|
for i, gobootbundle := range gobootbundles {
|
||||||
log.Fatalf("Failed to extract bootstrapper Go sources: %v", err)
|
if err := build.ExtractArchive(gobootbundle, pkgdir); err != nil {
|
||||||
}
|
log.Fatalf("Failed to extract bootstrapper Go sources: %v", err)
|
||||||
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".goboot")); err != nil {
|
}
|
||||||
log.Fatalf("Failed to rename bootstrapper Go source folder: %v", err)
|
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, fmt.Sprintf(".goboot-%d", i+1))); err != nil {
|
||||||
|
log.Fatalf("Failed to rename bootstrapper Go source folder: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Add builder Go source code
|
// Add builder Go source code
|
||||||
if err := build.ExtractArchive(gobundle, pkgdir); err != nil {
|
if err := build.ExtractArchive(gobundle, pkgdir); err != nil {
|
||||||
@@ -754,21 +869,26 @@ func doDebianSource(cmdline []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// downloadGoBootstrapSources downloads the Go source tarball that will be used
|
// downloadGoBootstrapSources downloads the Go source tarball(s) that will be used
|
||||||
// to bootstrap the builder Go.
|
// to bootstrap the builder Go.
|
||||||
func downloadGoBootstrapSources(cachedir string) string {
|
func downloadGoBootstrapSources(cachedir string) []string {
|
||||||
csdb := build.MustLoadChecksums("build/checksums.txt")
|
csdb := build.MustLoadChecksums("build/checksums.txt")
|
||||||
gobootVersion, err := build.Version(csdb, "ppa-builder")
|
|
||||||
if err != nil {
|
var bundles []string
|
||||||
log.Fatal(err)
|
for _, booter := range []string{"ppa-builder-1", "ppa-builder-2"} {
|
||||||
|
gobootVersion, err := build.Version(csdb, booter)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
file := fmt.Sprintf("go%s.src.tar.gz", gobootVersion)
|
||||||
|
url := "https://dl.google.com/go/" + file
|
||||||
|
dst := filepath.Join(cachedir, file)
|
||||||
|
if err := csdb.DownloadFile(url, dst); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
bundles = append(bundles, dst)
|
||||||
}
|
}
|
||||||
file := fmt.Sprintf("go%s.src.tar.gz", gobootVersion)
|
return bundles
|
||||||
url := "https://dl.google.com/go/" + file
|
|
||||||
dst := filepath.Join(cachedir, file)
|
|
||||||
if err := csdb.DownloadFile(url, dst); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// downloadGoSources downloads the Go source tarball.
|
// downloadGoSources downloads the Go source tarball.
|
||||||
@@ -846,10 +966,7 @@ type debPackage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type debMetadata struct {
|
type debMetadata struct {
|
||||||
Env build.Environment
|
Env build.Environment
|
||||||
GoBootPackage string
|
|
||||||
GoBootPath string
|
|
||||||
|
|
||||||
PackageName string
|
PackageName string
|
||||||
|
|
||||||
// go-ethereum version being built. Note that this
|
// go-ethereum version being built. Note that this
|
||||||
@@ -877,21 +994,19 @@ func (d debExecutable) Package() string {
|
|||||||
return d.BinaryName
|
return d.BinaryName
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDebMetadata(distro, goboot, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata {
|
func newDebMetadata(distro, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata {
|
||||||
if author == "" {
|
if author == "" {
|
||||||
// No signing key, use default author.
|
// No signing key, use default author.
|
||||||
author = "Ethereum Builds <fjl@ethereum.org>"
|
author = "Ethereum Builds <fjl@ethereum.org>"
|
||||||
}
|
}
|
||||||
return debMetadata{
|
return debMetadata{
|
||||||
GoBootPackage: goboot,
|
PackageName: name,
|
||||||
GoBootPath: debGoBootPaths[goboot],
|
Env: env,
|
||||||
PackageName: name,
|
Author: author,
|
||||||
Env: env,
|
Distro: distro,
|
||||||
Author: author,
|
Version: version,
|
||||||
Distro: distro,
|
Time: t.Format(time.RFC1123Z),
|
||||||
Version: version,
|
Executables: exes,
|
||||||
Time: t.Format(time.RFC1123Z),
|
|
||||||
Executables: exes,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Source: {{.Name}}
|
|||||||
Section: science
|
Section: science
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: {{.Author}}
|
Maintainer: {{.Author}}
|
||||||
Build-Depends: debhelper (>= 8.0.0), {{.GoBootPackage}}
|
Build-Depends: debhelper (>= 8.0.0), golang-go
|
||||||
Standards-Version: 3.9.5
|
Standards-Version: 3.9.5
|
||||||
Homepage: https://ethereum.org
|
Homepage: https://ethereum.org
|
||||||
Vcs-Git: https://github.com/ethereum/go-ethereum.git
|
Vcs-Git: https://github.com/ethereum/go-ethereum.git
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
# Launchpad rejects Go's access to $HOME, use custom folders
|
# Launchpad rejects Go's access to $HOME, use custom folders
|
||||||
export GOCACHE=/tmp/go-build
|
export GOCACHE=/tmp/go-build
|
||||||
export GOPATH=/tmp/gopath
|
export GOPATH=/tmp/gopath
|
||||||
export GOROOT_BOOTSTRAP={{.GoBootPath}}
|
export GOROOT_BOOTSTRAP=/usr/lib/go
|
||||||
|
|
||||||
override_dh_auto_clean:
|
override_dh_auto_clean:
|
||||||
# Don't try to be smart Launchpad, we know our build rules better than you
|
# Don't try to be smart Launchpad, we know our build rules better than you
|
||||||
@@ -19,8 +19,9 @@ override_dh_auto_build:
|
|||||||
#
|
#
|
||||||
# We're also shipping the bootstrapper as of Go 1.20 as it had minimum version
|
# We're also shipping the bootstrapper as of Go 1.20 as it had minimum version
|
||||||
# requirements opposed to older versions of Go.
|
# requirements opposed to older versions of Go.
|
||||||
(mv .goboot ../ && cd ../.goboot/src && ./make.bash)
|
(mv .goboot-1 ../ && cd ../.goboot-1/src && ./make.bash)
|
||||||
(mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot ./make.bash)
|
(mv .goboot-2 ../ && cd ../.goboot-2/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-1 ./make.bash)
|
||||||
|
(mv .go ../ && cd ../.go/src && GOROOT_BOOTSTRAP=`pwd`/../../.goboot-2 ./make.bash)
|
||||||
|
|
||||||
# We can't download external go modules within Launchpad, so we're shipping the
|
# We can't download external go modules within Launchpad, so we're shipping the
|
||||||
# entire dependency source cache with go-ethereum.
|
# entire dependency source cache with go-ethereum.
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ package tools
|
|||||||
import (
|
import (
|
||||||
// Tool imports for go:generate.
|
// Tool imports for go:generate.
|
||||||
_ "github.com/fjl/gencodec"
|
_ "github.com/fjl/gencodec"
|
||||||
_ "github.com/golang/protobuf/protoc-gen-go"
|
|
||||||
_ "golang.org/x/tools/cmd/stringer"
|
_ "golang.org/x/tools/cmd/stringer"
|
||||||
|
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -19,39 +19,21 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/blsync"
|
"github.com/ethereum/go-ethereum/beacon/blsync"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/debug"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/mattn/go-colorable"
|
|
||||||
"github.com/mattn/go-isatty"
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
verbosityFlag = &cli.IntFlag{
|
|
||||||
Name: "verbosity",
|
|
||||||
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
|
|
||||||
Value: 3,
|
|
||||||
Category: flags.LoggingCategory,
|
|
||||||
}
|
|
||||||
vmoduleFlag = &cli.StringFlag{
|
|
||||||
Name: "vmodule",
|
|
||||||
Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)",
|
|
||||||
Value: "",
|
|
||||||
Hidden: true,
|
|
||||||
Category: flags.LoggingCategory,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := flags.NewApp("beacon light syncer tool")
|
app := flags.NewApp("beacon light syncer tool")
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = flags.Merge([]cli.Flag{
|
||||||
utils.BeaconApiFlag,
|
utils.BeaconApiFlag,
|
||||||
utils.BeaconApiHeaderFlag,
|
utils.BeaconApiHeaderFlag,
|
||||||
utils.BeaconThresholdFlag,
|
utils.BeaconThresholdFlag,
|
||||||
@@ -63,11 +45,18 @@ func main() {
|
|||||||
//TODO datadir for optional permanent database
|
//TODO datadir for optional permanent database
|
||||||
utils.MainnetFlag,
|
utils.MainnetFlag,
|
||||||
utils.SepoliaFlag,
|
utils.SepoliaFlag,
|
||||||
utils.GoerliFlag,
|
|
||||||
utils.BlsyncApiFlag,
|
utils.BlsyncApiFlag,
|
||||||
utils.BlsyncJWTSecretFlag,
|
utils.BlsyncJWTSecretFlag,
|
||||||
verbosityFlag,
|
},
|
||||||
vmoduleFlag,
|
debug.Flags,
|
||||||
|
)
|
||||||
|
app.Before = func(ctx *cli.Context) error {
|
||||||
|
flags.MigrateGlobalFlags(ctx)
|
||||||
|
return debug.Setup(ctx)
|
||||||
|
}
|
||||||
|
app.After = func(ctx *cli.Context) error {
|
||||||
|
debug.Exit()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
app.Action = sync
|
app.Action = sync
|
||||||
|
|
||||||
@@ -78,14 +67,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sync(ctx *cli.Context) error {
|
func sync(ctx *cli.Context) error {
|
||||||
usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb"
|
|
||||||
output := io.Writer(os.Stderr)
|
|
||||||
if usecolor {
|
|
||||||
output = colorable.NewColorable(os.Stderr)
|
|
||||||
}
|
|
||||||
verbosity := log.FromLegacyLevel(ctx.Int(verbosityFlag.Name))
|
|
||||||
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(output, verbosity, usecolor)))
|
|
||||||
|
|
||||||
// set up blsync
|
// set up blsync
|
||||||
client := blsync.NewClient(ctx)
|
client := blsync.NewClient(ctx)
|
||||||
client.SetEngineRPC(makeRPCClient(ctx))
|
client.SetEngineRPC(makeRPCClient(ctx))
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ GLOBAL OPTIONS:
|
|||||||
--loglevel value log level to emit to the screen (default: 4)
|
--loglevel value log level to emit to the screen (default: 4)
|
||||||
--keystore value Directory for the keystore (default: "$HOME/.ethereum/keystore")
|
--keystore value Directory for the keystore (default: "$HOME/.ethereum/keystore")
|
||||||
--configdir value Directory for Clef configuration (default: "$HOME/.clef")
|
--configdir value Directory for Clef configuration (default: "$HOME/.clef")
|
||||||
--chainid value Chain id to use for signing (1=mainnet, 5=Goerli) (default: 1)
|
--chainid value Chain id to use for signing (1=mainnet, 17000=Holesky) (default: 1)
|
||||||
--lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength
|
--lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength
|
||||||
--nousb Disables monitoring for and managing USB hardware wallets
|
--nousb Disables monitoring for and managing USB hardware wallets
|
||||||
--pcscdpath value Path to the smartcard daemon (pcscd) socket file (default: "/run/pcscd/pcscd.comm")
|
--pcscdpath value Path to the smartcard daemon (pcscd) socket file (default: "/run/pcscd/pcscd.comm")
|
||||||
@@ -225,8 +225,8 @@ Response
|
|||||||
- `value` [number:optional]: amount of Wei to send with the transaction
|
- `value` [number:optional]: amount of Wei to send with the transaction
|
||||||
- `data` [data:optional]: input data
|
- `data` [data:optional]: input data
|
||||||
- `nonce` [number]: account nonce
|
- `nonce` [number]: account nonce
|
||||||
1. method signature [string:optional]
|
2. method signature [string:optional]
|
||||||
- The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected.
|
- The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected.
|
||||||
|
|
||||||
|
|
||||||
#### Result
|
#### Result
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ import (
|
|||||||
// TestImportRaw tests clef --importraw
|
// TestImportRaw tests clef --importraw
|
||||||
func TestImportRaw(t *testing.T) {
|
func TestImportRaw(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||||
t.Cleanup(func() { os.Remove(keyPath) })
|
|
||||||
|
|
||||||
t.Run("happy-path", func(t *testing.T) {
|
t.Run("happy-path", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -68,9 +67,8 @@ func TestImportRaw(t *testing.T) {
|
|||||||
// TestListAccounts tests clef --list-accounts
|
// TestListAccounts tests clef --list-accounts
|
||||||
func TestListAccounts(t *testing.T) {
|
func TestListAccounts(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||||
t.Cleanup(func() { os.Remove(keyPath) })
|
|
||||||
|
|
||||||
t.Run("no-accounts", func(t *testing.T) {
|
t.Run("no-accounts", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -97,9 +95,8 @@ func TestListAccounts(t *testing.T) {
|
|||||||
// TestListWallets tests clef --list-wallets
|
// TestListWallets tests clef --list-wallets
|
||||||
func TestListWallets(t *testing.T) {
|
func TestListWallets(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
keyPath := filepath.Join(os.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
keyPath := filepath.Join(t.TempDir(), fmt.Sprintf("%v-tempkey.test", t.Name()))
|
||||||
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
os.WriteFile(keyPath, []byte("0102030405060708090a0102030405060708090a0102030405060708090a0102"), 0777)
|
||||||
t.Cleanup(func() { os.Remove(keyPath) })
|
|
||||||
|
|
||||||
t.Run("no-accounts", func(t *testing.T) {
|
t.Run("no-accounts", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ var (
|
|||||||
chainIdFlag = &cli.Int64Flag{
|
chainIdFlag = &cli.Int64Flag{
|
||||||
Name: "chainid",
|
Name: "chainid",
|
||||||
Value: params.MainnetChainConfig.ChainID.Int64(),
|
Value: params.MainnetChainConfig.ChainID.Int64(),
|
||||||
Usage: "Chain id to use for signing (1=mainnet, 5=Goerli)",
|
Usage: "Chain id to use for signing (1=mainnet, 17000=Holesky)",
|
||||||
}
|
}
|
||||||
rpcPortFlag = &cli.IntFlag{
|
rpcPortFlag = &cli.IntFlag{
|
||||||
Name: "http.port",
|
Name: "http.port",
|
||||||
@@ -552,7 +552,7 @@ func listWallets(c *cli.Context) error {
|
|||||||
// accountImport imports a raw hexadecimal private key via CLI.
|
// accountImport imports a raw hexadecimal private key via CLI.
|
||||||
func accountImport(c *cli.Context) error {
|
func accountImport(c *cli.Context) error {
|
||||||
if c.Args().Len() != 1 {
|
if c.Args().Len() != 1 {
|
||||||
return errors.New("<keyfile> must be given as first argument.")
|
return errors.New("<keyfile> must be given as first argument")
|
||||||
}
|
}
|
||||||
internalApi, ui, err := initInternalApi(c)
|
internalApi, ui, err := initInternalApi(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ set to standard output. The following filters are supported:
|
|||||||
- `-limit <N>` limits the output set to N entries, taking the top N nodes by score
|
- `-limit <N>` limits the output set to N entries, taking the top N nodes by score
|
||||||
- `-ip <CIDR>` filters nodes by IP subnet
|
- `-ip <CIDR>` filters nodes by IP subnet
|
||||||
- `-min-age <duration>` filters nodes by 'first seen' time
|
- `-min-age <duration>` filters nodes by 'first seen' time
|
||||||
- `-eth-network <mainnet/goerli/sepolia/holesky>` filters nodes by "eth" ENR entry
|
- `-eth-network <mainnet/sepolia/holesky>` filters nodes by "eth" ENR entry
|
||||||
- `-les-server` filters nodes by LES server support
|
- `-les-server` filters nodes by LES server support
|
||||||
- `-snap` filters nodes by snap protocol support
|
- `-snap` filters nodes by snap protocol support
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -28,9 +29,11 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,6 +48,7 @@ var (
|
|||||||
discv4ResolveJSONCommand,
|
discv4ResolveJSONCommand,
|
||||||
discv4CrawlCommand,
|
discv4CrawlCommand,
|
||||||
discv4TestCommand,
|
discv4TestCommand,
|
||||||
|
discv4ListenCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
discv4PingCommand = &cli.Command{
|
discv4PingCommand = &cli.Command{
|
||||||
@@ -75,6 +79,14 @@ var (
|
|||||||
Flags: discoveryNodeFlags,
|
Flags: discoveryNodeFlags,
|
||||||
ArgsUsage: "<nodes.json file>",
|
ArgsUsage: "<nodes.json file>",
|
||||||
}
|
}
|
||||||
|
discv4ListenCommand = &cli.Command{
|
||||||
|
Name: "listen",
|
||||||
|
Usage: "Runs a discovery node",
|
||||||
|
Action: discv4Listen,
|
||||||
|
Flags: flags.Merge(discoveryNodeFlags, []cli.Flag{
|
||||||
|
httpAddrFlag,
|
||||||
|
}),
|
||||||
|
}
|
||||||
discv4CrawlCommand = &cli.Command{
|
discv4CrawlCommand = &cli.Command{
|
||||||
Name: "crawl",
|
Name: "crawl",
|
||||||
Usage: "Updates a nodes.json file with random nodes found in the DHT",
|
Usage: "Updates a nodes.json file with random nodes found in the DHT",
|
||||||
@@ -131,6 +143,10 @@ var (
|
|||||||
Usage: "Enode of the remote node under test",
|
Usage: "Enode of the remote node under test",
|
||||||
EnvVars: []string{"REMOTE_ENODE"},
|
EnvVars: []string{"REMOTE_ENODE"},
|
||||||
}
|
}
|
||||||
|
httpAddrFlag = &cli.StringFlag{
|
||||||
|
Name: "rpc",
|
||||||
|
Usage: "HTTP server listening address",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var discoveryNodeFlags = []cli.Flag{
|
var discoveryNodeFlags = []cli.Flag{
|
||||||
@@ -154,6 +170,27 @@ func discv4Ping(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func discv4Listen(ctx *cli.Context) error {
|
||||||
|
disc, _ := startV4(ctx)
|
||||||
|
defer disc.Close()
|
||||||
|
|
||||||
|
fmt.Println(disc.Self())
|
||||||
|
|
||||||
|
httpAddr := ctx.String(httpAddrFlag.Name)
|
||||||
|
if httpAddr == "" {
|
||||||
|
// Non-HTTP mode.
|
||||||
|
select {}
|
||||||
|
}
|
||||||
|
|
||||||
|
api := &discv4API{disc}
|
||||||
|
log.Info("Starting RPC API server", "addr", httpAddr)
|
||||||
|
srv := rpc.NewServer()
|
||||||
|
srv.RegisterName("discv4", api)
|
||||||
|
http.DefaultServeMux.Handle("/", srv)
|
||||||
|
httpsrv := http.Server{Addr: httpAddr, Handler: http.DefaultServeMux}
|
||||||
|
return httpsrv.ListenAndServe()
|
||||||
|
}
|
||||||
|
|
||||||
func discv4RequestRecord(ctx *cli.Context) error {
|
func discv4RequestRecord(ctx *cli.Context) error {
|
||||||
n := getNodeArg(ctx)
|
n := getNodeArg(ctx)
|
||||||
disc, _ := startV4(ctx)
|
disc, _ := startV4(ctx)
|
||||||
@@ -362,3 +399,23 @@ func parseBootnodes(ctx *cli.Context) ([]*enode.Node, error) {
|
|||||||
}
|
}
|
||||||
return nodes, nil
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type discv4API struct {
|
||||||
|
host *discover.UDPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *discv4API) LookupRandom(n int) (ns []*enode.Node) {
|
||||||
|
it := api.host.RandomNodes()
|
||||||
|
for len(ns) < n && it.Next() {
|
||||||
|
ns = append(ns, it.Node())
|
||||||
|
}
|
||||||
|
return ns
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *discv4API) Buckets() [][]discover.BucketNode {
|
||||||
|
return api.host.TableBuckets()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *discv4API) Self() *enode.Node {
|
||||||
|
return api.host.Self()
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ func (c *cloudflareClient) checkZone(name string) error {
|
|||||||
if !strings.HasSuffix(name, "."+zone.Name) {
|
if !strings.HasSuffix(name, "."+zone.Name) {
|
||||||
return fmt.Errorf("CloudFlare zone name %q does not match name %q to be deployed", zone.Name, name)
|
return fmt.Errorf("CloudFlare zone name %q does not match name %q to be deployed", zone.Name, name)
|
||||||
}
|
}
|
||||||
needPerms := map[string]bool{"#zone:edit": false, "#zone:read": false}
|
// Necessary permissions for Cloudlare management - Zone:Read, DNS:Read, Zone:Edit, DNS:Edit
|
||||||
|
needPerms := map[string]bool{"#zone:edit": false, "#zone:read": false, "#dns_records:read": false, "#dns_records:edit": false}
|
||||||
for _, perm := range zone.Permissions {
|
for _, perm := range zone.Permissions {
|
||||||
if _, ok := needPerms[perm]; ok {
|
if _, ok := needPerms[perm]; ok {
|
||||||
needPerms[perm] = true
|
needPerms[perm] = true
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ func (s *Suite) dial() (*Conn, error) {
|
|||||||
// dialAs attempts to dial a given node and perform a handshake using the given
|
// dialAs attempts to dial a given node and perform a handshake using the given
|
||||||
// private key.
|
// private key.
|
||||||
func (s *Suite) dialAs(key *ecdsa.PrivateKey) (*Conn, error) {
|
func (s *Suite) dialAs(key *ecdsa.PrivateKey) (*Conn, error) {
|
||||||
fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", s.Dest.IP(), s.Dest.TCP()))
|
tcpEndpoint, _ := s.Dest.TCPEndpoint()
|
||||||
|
fd, err := net.Dial("tcp", tcpEndpoint.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/internal/utesting"
|
"github.com/ethereum/go-ethereum/internal/utesting"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Conn) snapRequest(code uint64, msg any) (any, error) {
|
func (c *Conn) snapRequest(code uint64, msg any) (any, error) {
|
||||||
@@ -905,7 +904,7 @@ func (s *Suite) snapGetByteCodes(t *utesting.T, tc *byteCodesTest) error {
|
|||||||
// that the serving node is missing
|
// that the serving node is missing
|
||||||
var (
|
var (
|
||||||
bytecodes = res.Codes
|
bytecodes = res.Codes
|
||||||
hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
|
hasher = crypto.NewKeccakState()
|
||||||
hash = make([]byte, 32)
|
hash = make([]byte, 32)
|
||||||
codes = make([][]byte, len(req.Hashes))
|
codes = make([][]byte, len(req.Hashes))
|
||||||
)
|
)
|
||||||
@@ -964,7 +963,7 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
|
|||||||
|
|
||||||
// Cross reference the requested trienodes with the response to find gaps
|
// Cross reference the requested trienodes with the response to find gaps
|
||||||
// that the serving node is missing
|
// that the serving node is missing
|
||||||
hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
|
hasher := crypto.NewKeccakState()
|
||||||
hash := make([]byte, 32)
|
hash := make([]byte, 32)
|
||||||
trienodes := res.Nodes
|
trienodes := res.Nodes
|
||||||
if got, want := len(trienodes), len(tc.expHashes); got != want {
|
if got, want := len(trienodes), len(tc.expHashes); got != want {
|
||||||
|
|||||||
@@ -849,7 +849,16 @@ func (s *Suite) TestBlobViolations(t *utesting.T) {
|
|||||||
if code, _, err := conn.Read(); err != nil {
|
if code, _, err := conn.Read(); err != nil {
|
||||||
t.Fatalf("expected disconnect on blob violation, got err: %v", err)
|
t.Fatalf("expected disconnect on blob violation, got err: %v", err)
|
||||||
} else if code != discMsg {
|
} else if code != discMsg {
|
||||||
t.Fatalf("expected disconnect on blob violation, got msg code: %d", code)
|
if code == protoOffset(ethProto)+eth.NewPooledTransactionHashesMsg {
|
||||||
|
// sometimes we'll get a blob transaction hashes announcement before the disconnect
|
||||||
|
// because blob transactions are scheduled to be fetched right away.
|
||||||
|
if code, _, err = conn.Read(); err != nil {
|
||||||
|
t.Fatalf("expected disconnect on blob violation, got err on second read: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if code != discMsg {
|
||||||
|
t.Fatalf("expected disconnect on blob violation, got msg code: %d", code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeJWTSecret() (string, [32]byte, error) {
|
func makeJWTSecret(t *testing.T) (string, [32]byte, error) {
|
||||||
var secret [32]byte
|
var secret [32]byte
|
||||||
if _, err := crand.Read(secret[:]); err != nil {
|
if _, err := crand.Read(secret[:]); err != nil {
|
||||||
return "", secret, fmt.Errorf("failed to create jwt secret: %v", err)
|
return "", secret, fmt.Errorf("failed to create jwt secret: %v", err)
|
||||||
}
|
}
|
||||||
jwtPath := filepath.Join(os.TempDir(), "jwt_secret")
|
jwtPath := filepath.Join(t.TempDir(), "jwt_secret")
|
||||||
if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil {
|
if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil {
|
||||||
return "", secret, fmt.Errorf("failed to prepare jwt secret file: %v", err)
|
return "", secret, fmt.Errorf("failed to prepare jwt secret file: %v", err)
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ func makeJWTSecret() (string, [32]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEthSuite(t *testing.T) {
|
func TestEthSuite(t *testing.T) {
|
||||||
jwtPath, secret, err := makeJWTSecret()
|
jwtPath, secret, err := makeJWTSecret(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not make jwt secret: %v", err)
|
t.Fatalf("could not make jwt secret: %v", err)
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ func TestEthSuite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSnapSuite(t *testing.T) {
|
func TestSnapSuite(t *testing.T) {
|
||||||
jwtPath, secret, err := makeJWTSecret()
|
jwtPath, secret, err := makeJWTSecret(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not make jwt secret: %v", err)
|
t.Fatalf("could not make jwt secret: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,16 +53,18 @@ func newTestEnv(remote string, listen1, listen2 string) *testenv {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if node.IP() == nil || node.UDP() == 0 {
|
if !node.IPAddr().IsValid() || node.UDP() == 0 {
|
||||||
var ip net.IP
|
var ip net.IP
|
||||||
var tcpPort, udpPort int
|
var tcpPort, udpPort int
|
||||||
if ip = node.IP(); ip == nil {
|
if node.IPAddr().IsValid() {
|
||||||
|
ip = node.IPAddr().AsSlice()
|
||||||
|
} else {
|
||||||
ip = net.ParseIP("127.0.0.1")
|
ip = net.ParseIP("127.0.0.1")
|
||||||
}
|
}
|
||||||
if tcpPort = node.TCP(); tcpPort == 0 {
|
if tcpPort = node.TCP(); tcpPort == 0 {
|
||||||
tcpPort = 30303
|
tcpPort = 30303
|
||||||
}
|
}
|
||||||
if udpPort = node.TCP(); udpPort == 0 {
|
if udpPort = node.UDP(); udpPort == 0 {
|
||||||
udpPort = 30303
|
udpPort = 30303
|
||||||
}
|
}
|
||||||
node = enode.NewV4(node.Pubkey(), ip, tcpPort, udpPort)
|
node = enode.NewV4(node.Pubkey(), ip, tcpPort, udpPort)
|
||||||
@@ -110,7 +112,7 @@ func (te *testenv) localEndpoint(c net.PacketConn) v4wire.Endpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (te *testenv) remoteEndpoint() v4wire.Endpoint {
|
func (te *testenv) remoteEndpoint() v4wire.Endpoint {
|
||||||
return v4wire.NewEndpoint(te.remoteAddr, 0)
|
return v4wire.NewEndpoint(te.remoteAddr.AddrPort(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(ns []v4wire.Node, key v4wire.Pubkey) bool {
|
func contains(ns []v4wire.Node, key v4wire.Pubkey) bool {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -205,11 +205,11 @@ func trueFilter(args []string) (nodeFilter, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ipFilter(args []string) (nodeFilter, error) {
|
func ipFilter(args []string) (nodeFilter, error) {
|
||||||
_, cidr, err := net.ParseCIDR(args[0])
|
prefix, err := netip.ParsePrefix(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f := func(n nodeJSON) bool { return cidr.Contains(n.N.IP()) }
|
f := func(n nodeJSON) bool { return prefix.Contains(n.N.IPAddr()) }
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,8 +230,6 @@ func ethFilter(args []string) (nodeFilter, error) {
|
|||||||
switch args[0] {
|
switch args[0] {
|
||||||
case "mainnet":
|
case "mainnet":
|
||||||
filter = forkid.NewStaticFilter(params.MainnetChainConfig, core.DefaultGenesisBlock().ToBlock())
|
filter = forkid.NewStaticFilter(params.MainnetChainConfig, core.DefaultGenesisBlock().ToBlock())
|
||||||
case "goerli":
|
|
||||||
filter = forkid.NewStaticFilter(params.GoerliChainConfig, core.DefaultGoerliGenesisBlock().ToBlock())
|
|
||||||
case "sepolia":
|
case "sepolia":
|
||||||
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, core.DefaultSepoliaGenesisBlock().ToBlock())
|
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, core.DefaultSepoliaGenesisBlock().ToBlock())
|
||||||
case "holesky":
|
case "holesky":
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ var (
|
|||||||
|
|
||||||
func rlpxPing(ctx *cli.Context) error {
|
func rlpxPing(ctx *cli.Context) error {
|
||||||
n := getNodeArg(ctx)
|
n := getNodeArg(ctx)
|
||||||
fd, err := net.Dial("tcp", fmt.Sprintf("%v:%d", n.IP(), n.TCP()))
|
tcpEndpoint, ok := n.TCPEndpoint()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("node has no TCP endpoint")
|
||||||
|
}
|
||||||
|
fd, err := net.Dial("tcp", tcpEndpoint.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -105,7 +109,7 @@ func rlpxPing(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
return fmt.Errorf("received disconnect message: %v", msg[0])
|
return fmt.Errorf("received disconnect message: %v", msg[0])
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid message code %d, expected handshake (code zero)", code)
|
return fmt.Errorf("invalid message code %d, expected handshake (code zero) or disconnect (code one)", code)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ The `evm t8n` tool is a stateless state transition utility. It is a utility
|
|||||||
which can
|
which can
|
||||||
|
|
||||||
1. Take a prestate, including
|
1. Take a prestate, including
|
||||||
- Accounts,
|
- Accounts,
|
||||||
- Block context information,
|
- Block context information,
|
||||||
- Previous blockshashes (*optional)
|
- Previous blockshashes (*optional)
|
||||||
2. Apply a set of transactions,
|
2. Apply a set of transactions,
|
||||||
3. Apply a mining-reward (*optional),
|
3. Apply a mining-reward (*optional),
|
||||||
4. And generate a post-state, including
|
4. And generate a post-state, including
|
||||||
- State root, transaction root, receipt root,
|
- State root, transaction root, receipt root,
|
||||||
- Information about rejected transactions,
|
- Information about rejected transactions,
|
||||||
- Optionally: a full or partial post-state dump
|
- Optionally: a full or partial post-state dump
|
||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func blockTestCmd(ctx *cli.Context) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
test := tests[name]
|
test := tests[name]
|
||||||
if err := test.Run(false, rawdb.HashScheme, tracer, func(res error, chain *core.BlockChain) {
|
if err := test.Run(false, rawdb.HashScheme, false, tracer, func(res error, chain *core.BlockChain) {
|
||||||
if ctx.Bool(DumpFlag.Name) {
|
if ctx.Bool(DumpFlag.Name) {
|
||||||
if state, _ := chain.State(); state != nil {
|
if state, _ := chain.State(); state != nil {
|
||||||
fmt.Println(string(state.Dump(nil)))
|
fmt.Println(string(state.Dump(nil)))
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ func (i *bbInput) ToBlock() *types.Block {
|
|||||||
if i.Header.Difficulty != nil {
|
if i.Header.Difficulty != nil {
|
||||||
header.Difficulty = i.Header.Difficulty
|
header.Difficulty = i.Header.Difficulty
|
||||||
}
|
}
|
||||||
return types.NewBlockWithHeader(header).WithBody(i.Txs, i.Ommers).WithWithdrawals(i.Withdrawals)
|
return types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: i.Txs, Uncles: i.Ommers, Withdrawals: i.Withdrawals})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SealBlock seals the given block using the configured engine.
|
// SealBlock seals the given block using the configured engine.
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ type ExecutionResult struct {
|
|||||||
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
|
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
|
||||||
CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"`
|
CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"`
|
||||||
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
|
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
|
||||||
|
RequestsHash *common.Hash `json:"requestsRoot,omitempty"`
|
||||||
|
DepositRequests *types.Deposits `json:"depositRequests,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ommer struct {
|
type ommer struct {
|
||||||
@@ -196,7 +198,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
|
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
||||||
}
|
}
|
||||||
|
if pre.Env.BlockHashes != nil && chainConfig.IsPrague(new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) {
|
||||||
|
var (
|
||||||
|
prevNumber = pre.Env.Number - 1
|
||||||
|
prevHash = pre.Env.BlockHashes[math.HexOrDecimal64(prevNumber)]
|
||||||
|
evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
|
||||||
|
)
|
||||||
|
core.ProcessParentBlockHash(prevHash, evm, statedb)
|
||||||
|
}
|
||||||
for i := 0; txIt.Next(); i++ {
|
for i := 0; txIt.Next(); i++ {
|
||||||
tx, err := txIt.Tx()
|
tx, err := txIt.Tx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -306,7 +315,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
if tracer.Hooks.OnTxEnd != nil {
|
if tracer.Hooks.OnTxEnd != nil {
|
||||||
tracer.Hooks.OnTxEnd(receipt, nil)
|
tracer.Hooks.OnTxEnd(receipt, nil)
|
||||||
}
|
}
|
||||||
writeTraceResult(tracer, traceOutput)
|
if err = writeTraceResult(tracer, traceOutput); err != nil {
|
||||||
|
log.Warn("Error writing tracer output", "err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +334,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
var (
|
var (
|
||||||
blockReward = big.NewInt(miningReward)
|
blockReward = big.NewInt(miningReward)
|
||||||
minerReward = new(big.Int).Set(blockReward)
|
minerReward = new(big.Int).Set(blockReward)
|
||||||
perOmmer = new(big.Int).Div(blockReward, big.NewInt(32))
|
perOmmer = new(big.Int).Rsh(blockReward, 5)
|
||||||
)
|
)
|
||||||
for _, ommer := range pre.Env.Ommers {
|
for _, ommer := range pre.Env.Ommers {
|
||||||
// Add 1/32th for each ommer included
|
// Add 1/32th for each ommer included
|
||||||
@@ -332,7 +343,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
reward := big.NewInt(8)
|
reward := big.NewInt(8)
|
||||||
reward.Sub(reward, new(big.Int).SetUint64(ommer.Delta))
|
reward.Sub(reward, new(big.Int).SetUint64(ommer.Delta))
|
||||||
reward.Mul(reward, blockReward)
|
reward.Mul(reward, blockReward)
|
||||||
reward.Div(reward, big.NewInt(8))
|
reward.Rsh(reward, 3)
|
||||||
statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward), tracing.BalanceIncreaseRewardMineUncle)
|
statedb.AddBalance(ommer.Address, uint256.MustFromBig(reward), tracing.BalanceIncreaseRewardMineUncle)
|
||||||
}
|
}
|
||||||
statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward), tracing.BalanceIncreaseRewardMineBlock)
|
statedb.AddBalance(pre.Env.Coinbase, uint256.MustFromBig(minerReward), tracing.BalanceIncreaseRewardMineBlock)
|
||||||
@@ -368,9 +379,31 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
execRs.CurrentExcessBlobGas = (*math.HexOrDecimal64)(&excessBlobGas)
|
execRs.CurrentExcessBlobGas = (*math.HexOrDecimal64)(&excessBlobGas)
|
||||||
execRs.CurrentBlobGasUsed = (*math.HexOrDecimal64)(&blobGasUsed)
|
execRs.CurrentBlobGasUsed = (*math.HexOrDecimal64)(&blobGasUsed)
|
||||||
}
|
}
|
||||||
|
if chainConfig.IsPrague(vmContext.BlockNumber, vmContext.Time) {
|
||||||
|
// Parse the requests from the logs
|
||||||
|
var allLogs []*types.Log
|
||||||
|
for _, receipt := range receipts {
|
||||||
|
allLogs = append(allLogs, receipt.Logs...)
|
||||||
|
}
|
||||||
|
requests, err := core.ParseDepositLogs(allLogs, chainConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err))
|
||||||
|
}
|
||||||
|
// Calculate the requests root
|
||||||
|
h := types.DeriveSha(requests, trie.NewStackTrie(nil))
|
||||||
|
execRs.RequestsHash = &h
|
||||||
|
// Get the deposits from the requests
|
||||||
|
deposits := make(types.Deposits, 0)
|
||||||
|
for _, req := range requests {
|
||||||
|
if dep, ok := req.Inner().(*types.Deposit); ok {
|
||||||
|
deposits = append(deposits, dep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
execRs.DepositRequests = &deposits
|
||||||
|
}
|
||||||
// Re-create statedb instance with new root upon the updated database
|
// Re-create statedb instance with new root upon the updated database
|
||||||
// for accessing latest states.
|
// for accessing latest states.
|
||||||
statedb, err = state.New(root, statedb.Database(), nil)
|
statedb, err = state.New(root, statedb.Database())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
||||||
}
|
}
|
||||||
@@ -379,8 +412,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
||||||
sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
|
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
|
sdb := state.NewDatabase(tdb, nil)
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||||
for addr, a := range accounts {
|
for addr, a := range accounts {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce)
|
statedb.SetNonce(addr, a.Nonce)
|
||||||
@@ -391,7 +425,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
|
|||||||
}
|
}
|
||||||
// Commit and re-open to start with a clean state.
|
// Commit and re-open to start with a clean state.
|
||||||
root, _ := statedb.Commit(0, false)
|
root, _ := statedb.Commit(0, false)
|
||||||
statedb, _ = state.New(root, sdb, nil)
|
statedb, _ = state.New(root, sdb)
|
||||||
return statedb
|
return statedb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ func Transition(ctx *cli.Context) error {
|
|||||||
// Set the chain id
|
// Set the chain id
|
||||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
|
||||||
|
|
||||||
if txIt, err = loadTransactions(txStr, inputData, prestate.Env, chainConfig); err != nil {
|
if txIt, err = loadTransactions(txStr, inputData, chainConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
if err := applyLondonChecks(&prestate.Env, chainConfig); err != nil {
|
||||||
@@ -217,7 +217,7 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if env.ParentBaseFee == nil || env.Number == 0 {
|
if env.ParentBaseFee == nil || env.Number == 0 {
|
||||||
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
|
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'parentBaseFee' in env section"))
|
||||||
}
|
}
|
||||||
env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{
|
env.BaseFee = eip1559.CalcBaseFee(chainConfig, &types.Header{
|
||||||
Number: new(big.Int).SetUint64(env.Number - 1),
|
Number: new(big.Int).SetUint64(env.Number - 1),
|
||||||
@@ -296,7 +296,7 @@ func (g Alloc) OnAccount(addr *common.Address, dumpAccount state.DumpAccount) {
|
|||||||
balance, _ := new(big.Int).SetString(dumpAccount.Balance, 0)
|
balance, _ := new(big.Int).SetString(dumpAccount.Balance, 0)
|
||||||
var storage map[common.Hash]common.Hash
|
var storage map[common.Hash]common.Hash
|
||||||
if dumpAccount.Storage != nil {
|
if dumpAccount.Storage != nil {
|
||||||
storage = make(map[common.Hash]common.Hash)
|
storage = make(map[common.Hash]common.Hash, len(dumpAccount.Storage))
|
||||||
for k, v := range dumpAccount.Storage {
|
for k, v := range dumpAccount.Storage {
|
||||||
storage[k] = common.HexToHash(v)
|
storage[k] = common.HexToHash(v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran
|
|||||||
return signedTxs, nil
|
return signedTxs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (txIterator, error) {
|
func loadTransactions(txStr string, inputData *input, chainConfig *params.ChainConfig) (txIterator, error) {
|
||||||
var txsWithKeys []*txWithKey
|
var txsWithKeys []*txWithKey
|
||||||
if txStr != stdinSelector {
|
if txStr != stdinSelector {
|
||||||
data, err := os.ReadFile(txStr)
|
data, err := os.ReadFile(txStr)
|
||||||
|
|||||||
@@ -155,14 +155,13 @@ func runCmd(ctx *cli.Context) error {
|
|||||||
})
|
})
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
genesis := genesisConfig.MustCommit(db, triedb)
|
genesis := genesisConfig.MustCommit(db, triedb)
|
||||||
sdb := state.NewDatabaseWithNodeDB(db, triedb)
|
sdb := state.NewDatabase(triedb, nil)
|
||||||
statedb, _ = state.New(genesis.Root(), sdb, nil)
|
statedb, _ = state.New(genesis.Root(), sdb)
|
||||||
chainConfig = genesisConfig.Config
|
chainConfig = genesisConfig.Config
|
||||||
|
|
||||||
if ctx.String(SenderFlag.Name) != "" {
|
if ctx.String(SenderFlag.Name) != "" {
|
||||||
sender = common.HexToAddress(ctx.String(SenderFlag.Name))
|
sender = common.HexToAddress(ctx.String(SenderFlag.Name))
|
||||||
}
|
}
|
||||||
statedb.CreateAccount(sender)
|
|
||||||
|
|
||||||
if ctx.String(ReceiverFlag.Name) != "" {
|
if ctx.String(ReceiverFlag.Name) != "" {
|
||||||
receiver = common.HexToAddress(ctx.String(ReceiverFlag.Name))
|
receiver = common.HexToAddress(ctx.String(ReceiverFlag.Name))
|
||||||
@@ -222,6 +221,7 @@ func runCmd(ctx *cli.Context) error {
|
|||||||
Time: genesisConfig.Timestamp,
|
Time: genesisConfig.Timestamp,
|
||||||
Coinbase: genesisConfig.Coinbase,
|
Coinbase: genesisConfig.Coinbase,
|
||||||
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
|
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
|
||||||
|
BaseFee: genesisConfig.BaseFee,
|
||||||
BlobHashes: blobHashes,
|
BlobHashes: blobHashes,
|
||||||
BlobBaseFee: blobBaseFee,
|
BlobBaseFee: blobBaseFee,
|
||||||
EVMConfig: vm.Config{
|
EVMConfig: vm.Config{
|
||||||
@@ -277,7 +277,7 @@ func runCmd(ctx *cli.Context) error {
|
|||||||
fmt.Printf("Failed to commit changes %v\n", err)
|
fmt.Printf("Failed to commit changes %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dumpdb, err := state.New(root, sdb, nil)
|
dumpdb, err := state.New(root, sdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to open statedb %v\n", err)
|
fmt.Printf("Failed to open statedb %v\n", err)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func runStateTest(fname string, cfg vm.Config, dump bool) error {
|
|||||||
result.Root = &root
|
result.Root = &root
|
||||||
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
||||||
if dump { // Dump any state to aid debugging
|
if dump { // Dump any state to aid debugging
|
||||||
cpy, _ := state.New(root, tstate.StateDB.Database(), nil)
|
cpy, _ := state.New(root, tstate.StateDB.Database())
|
||||||
dump := cpy.RawDump(nil)
|
dump := cpy.RawDump(nil)
|
||||||
result.State = &dump
|
result.State = &dump
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ func TestT8n(t *testing.T) {
|
|||||||
{ // Test post-merge transition
|
{ // Test post-merge transition
|
||||||
base: "./testdata/24",
|
base: "./testdata/24",
|
||||||
input: t8nInput{
|
input: t8nInput{
|
||||||
"alloc.json", "txs.json", "env.json", "Merge", "",
|
"alloc.json", "txs.json", "env.json", "Paris", "",
|
||||||
},
|
},
|
||||||
output: t8nOutput{alloc: true, result: true},
|
output: t8nOutput{alloc: true, result: true},
|
||||||
expOut: "exp.json",
|
expOut: "exp.json",
|
||||||
@@ -242,7 +242,7 @@ func TestT8n(t *testing.T) {
|
|||||||
{ // Test post-merge transition where input is missing random
|
{ // Test post-merge transition where input is missing random
|
||||||
base: "./testdata/24",
|
base: "./testdata/24",
|
||||||
input: t8nInput{
|
input: t8nInput{
|
||||||
"alloc.json", "txs.json", "env-missingrandom.json", "Merge", "",
|
"alloc.json", "txs.json", "env-missingrandom.json", "Paris", "",
|
||||||
},
|
},
|
||||||
output: t8nOutput{alloc: false, result: false},
|
output: t8nOutput{alloc: false, result: false},
|
||||||
expExitCode: 3,
|
expExitCode: 3,
|
||||||
@@ -250,7 +250,7 @@ func TestT8n(t *testing.T) {
|
|||||||
{ // Test base fee calculation
|
{ // Test base fee calculation
|
||||||
base: "./testdata/25",
|
base: "./testdata/25",
|
||||||
input: t8nInput{
|
input: t8nInput{
|
||||||
"alloc.json", "txs.json", "env.json", "Merge", "",
|
"alloc.json", "txs.json", "env.json", "Paris", "",
|
||||||
},
|
},
|
||||||
output: t8nOutput{alloc: true, result: true},
|
output: t8nOutput{alloc: true, result: true},
|
||||||
expOut: "exp.json",
|
expOut: "exp.json",
|
||||||
@@ -378,7 +378,7 @@ func TestT8nTracing(t *testing.T) {
|
|||||||
{
|
{
|
||||||
base: "./testdata/32",
|
base: "./testdata/32",
|
||||||
input: t8nInput{
|
input: t8nInput{
|
||||||
"alloc.json", "txs.json", "env.json", "Merge", "",
|
"alloc.json", "txs.json", "env.json", "Paris", "",
|
||||||
},
|
},
|
||||||
extraArgs: []string{"--trace", "--trace.callframes"},
|
extraArgs: []string{"--trace", "--trace.callframes"},
|
||||||
expectedTraces: []string{"trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl"},
|
expectedTraces: []string{"trace-0-0x47806361c0fa084be3caa18afe8c48156747c01dbdfc1ee11b5aecdbe4fcf23e.jsonl"},
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@@ -222,22 +221,23 @@ func initGenesis(ctx *cli.Context) error {
|
|||||||
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
||||||
overrides.OverrideVerkle = &v
|
overrides.OverrideVerkle = &v
|
||||||
}
|
}
|
||||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
|
||||||
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("Failed to open database: %v", err)
|
|
||||||
}
|
|
||||||
defer chaindb.Close()
|
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
chaindb, err := stack.OpenDatabaseWithFreezer("chaindata", 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
|
||||||
defer triedb.Close()
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to open database: %v", err)
|
||||||
_, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("Failed to write genesis block: %v", err)
|
|
||||||
}
|
|
||||||
log.Info("Successfully wrote genesis state", "database", name, "hash", hash)
|
|
||||||
}
|
}
|
||||||
|
defer chaindb.Close()
|
||||||
|
|
||||||
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
||||||
|
defer triedb.Close()
|
||||||
|
|
||||||
|
_, hash, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to write genesis block: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Successfully wrote genesis state", "database", "chaindata", "hash", hash)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,29 +259,22 @@ func dumpGenesis(ctx *cli.Context) error {
|
|||||||
|
|
||||||
// dump whatever already exists in the datadir
|
// dump whatever already exists in the datadir
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
|
||||||
db, err := stack.OpenDatabase(name, 0, 0, "", true)
|
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
genesis, err := core.ReadGenesis(db)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("failed to read genesis: %s", err)
|
|
||||||
}
|
|
||||||
db.Close()
|
|
||||||
|
|
||||||
if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil {
|
db, err := stack.OpenDatabase("chaindata", 0, 0, "", true)
|
||||||
utils.Fatalf("could not encode stored genesis: %s", err)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.DataDirFlag.Name) {
|
defer db.Close()
|
||||||
utils.Fatalf("no existing datadir at %s", stack.Config().DataDir)
|
|
||||||
|
genesis, err = core.ReadGenesis(db)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("failed to read genesis: %s", err)
|
||||||
}
|
}
|
||||||
utils.Fatalf("no network preset provided, and no genesis exists in the default datadir")
|
|
||||||
|
if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil {
|
||||||
|
utils.Fatalf("could not encode stored genesis: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +330,7 @@ func importChain(ctx *cli.Context) error {
|
|||||||
fmt.Printf("Import done in %v.\n\n", time.Since(start))
|
fmt.Printf("Import done in %v.\n\n", time.Since(start))
|
||||||
|
|
||||||
// Output pre-compaction stats mostly to see the import trashing
|
// Output pre-compaction stats mostly to see the import trashing
|
||||||
showLeveldbStats(db)
|
showDBStats(db)
|
||||||
|
|
||||||
// Print the memory statistics used by the importing
|
// Print the memory statistics used by the importing
|
||||||
mem := new(runtime.MemStats)
|
mem := new(runtime.MemStats)
|
||||||
@@ -360,7 +353,7 @@ func importChain(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
|
fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
|
||||||
|
|
||||||
showLeveldbStats(db)
|
showDBStats(db)
|
||||||
return importErr
|
return importErr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,8 +419,6 @@ func importHistory(ctx *cli.Context) error {
|
|||||||
network = "mainnet"
|
network = "mainnet"
|
||||||
case ctx.Bool(utils.SepoliaFlag.Name):
|
case ctx.Bool(utils.SepoliaFlag.Name):
|
||||||
network = "sepolia"
|
network = "sepolia"
|
||||||
case ctx.Bool(utils.GoerliFlag.Name):
|
|
||||||
network = "goerli"
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No network flag set, try to determine network based on files
|
// No network flag set, try to determine network based on files
|
||||||
@@ -516,7 +507,7 @@ func importPreimages(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDumpConfig(ctx *cli.Context, stack *node.Node, db ethdb.Database) (*state.DumpConfig, common.Hash, error) {
|
func parseDumpConfig(ctx *cli.Context, db ethdb.Database) (*state.DumpConfig, common.Hash, error) {
|
||||||
var header *types.Header
|
var header *types.Header
|
||||||
if ctx.NArg() > 1 {
|
if ctx.NArg() > 1 {
|
||||||
return nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg())
|
return nil, common.Hash{}, fmt.Errorf("expected 1 argument (number or hash), got %d", ctx.NArg())
|
||||||
@@ -560,7 +551,7 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node, db ethdb.Database) (*st
|
|||||||
default:
|
default:
|
||||||
return nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg)
|
return nil, common.Hash{}, fmt.Errorf("invalid start argument: %x. 20 or 32 hex-encoded bytes required", startArg)
|
||||||
}
|
}
|
||||||
var conf = &state.DumpConfig{
|
conf := &state.DumpConfig{
|
||||||
SkipCode: ctx.Bool(utils.ExcludeCodeFlag.Name),
|
SkipCode: ctx.Bool(utils.ExcludeCodeFlag.Name),
|
||||||
SkipStorage: ctx.Bool(utils.ExcludeStorageFlag.Name),
|
SkipStorage: ctx.Bool(utils.ExcludeStorageFlag.Name),
|
||||||
OnlyWithAddresses: !ctx.Bool(utils.IncludeIncompletesFlag.Name),
|
OnlyWithAddresses: !ctx.Bool(utils.IncludeIncompletesFlag.Name),
|
||||||
@@ -580,14 +571,14 @@ func dump(ctx *cli.Context) error {
|
|||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
conf, root, err := parseDumpConfig(ctx, stack, db)
|
conf, root, err := parseDumpConfig(ctx, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
|
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil)
|
state, err := state.New(root, state.NewDatabase(triedb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ var tomlSettings = toml.Config{
|
|||||||
},
|
},
|
||||||
MissingField: func(rt reflect.Type, field string) error {
|
MissingField: func(rt reflect.Type, field string) error {
|
||||||
id := fmt.Sprintf("%s.%s", rt.String(), field)
|
id := fmt.Sprintf("%s.%s", rt.String(), field)
|
||||||
if deprecated(id) {
|
if deprecatedConfigFields[id] {
|
||||||
log.Warn("Config field is deprecated and won't have an effect", "name", id)
|
log.Warn(fmt.Sprintf("Config field '%s' is deprecated and won't have any effect.", id))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var link string
|
var link string
|
||||||
@@ -87,6 +87,19 @@ var tomlSettings = toml.Config{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var deprecatedConfigFields = map[string]bool{
|
||||||
|
"ethconfig.Config.EVMInterpreter": true,
|
||||||
|
"ethconfig.Config.EWASMInterpreter": true,
|
||||||
|
"ethconfig.Config.TrieCleanCacheJournal": true,
|
||||||
|
"ethconfig.Config.TrieCleanCacheRejournal": true,
|
||||||
|
"ethconfig.Config.LightServ": true,
|
||||||
|
"ethconfig.Config.LightIngress": true,
|
||||||
|
"ethconfig.Config.LightEgress": true,
|
||||||
|
"ethconfig.Config.LightPeers": true,
|
||||||
|
"ethconfig.Config.LightNoPrune": true,
|
||||||
|
"ethconfig.Config.LightNoSyncServe": true,
|
||||||
|
}
|
||||||
|
|
||||||
type ethstatsConfig struct {
|
type ethstatsConfig struct {
|
||||||
URL string `toml:",omitempty"`
|
URL string `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
@@ -314,21 +327,6 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deprecated(field string) bool {
|
|
||||||
switch field {
|
|
||||||
case "ethconfig.Config.EVMInterpreter":
|
|
||||||
return true
|
|
||||||
case "ethconfig.Config.EWASMInterpreter":
|
|
||||||
return true
|
|
||||||
case "ethconfig.Config.TrieCleanCacheJournal":
|
|
||||||
return true
|
|
||||||
case "ethconfig.Config.TrieCleanCacheRejournal":
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error {
|
func setAccountManagerBackends(conf *node.Config, am *accounts.Manager, keydir string) error {
|
||||||
scryptN := keystore.StandardScryptN
|
scryptN := keystore.StandardScryptN
|
||||||
scryptP := keystore.StandardScryptP
|
scryptP := keystore.StandardScryptP
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ipcAPIs = "admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0"
|
ipcAPIs = "admin:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0"
|
||||||
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
|
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,10 +38,10 @@ const (
|
|||||||
// memory and disk IO. If the args don't set --datadir, the
|
// memory and disk IO. If the args don't set --datadir, the
|
||||||
// child g gets a temporary data directory.
|
// child g gets a temporary data directory.
|
||||||
func runMinimalGeth(t *testing.T, args ...string) *testgeth {
|
func runMinimalGeth(t *testing.T, args ...string) *testgeth {
|
||||||
// --goerli to make the 'writing genesis to disk' faster (no accounts)
|
// --holesky to make the 'writing genesis to disk' faster (no accounts)
|
||||||
// --networkid=1337 to avoid cache bump
|
// --networkid=1337 to avoid cache bump
|
||||||
// --syncmode=full to avoid allocating fast sync bloom
|
// --syncmode=full to avoid allocating fast sync bloom
|
||||||
allArgs := []string{"--goerli", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0",
|
allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0",
|
||||||
"--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64",
|
"--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64",
|
||||||
"--datadir.minfreedisk", "0"}
|
"--datadir.minfreedisk", "0"}
|
||||||
return runGeth(t, append(allArgs, args...)...)
|
return runGeth(t, append(allArgs, args...)...)
|
||||||
@@ -62,7 +62,7 @@ func TestConsoleWelcome(t *testing.T) {
|
|||||||
geth.SetTemplateFunc("gover", runtime.Version)
|
geth.SetTemplateFunc("gover", runtime.Version)
|
||||||
geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
||||||
geth.SetTemplateFunc("niltime", func() string {
|
geth.SetTemplateFunc("niltime", func() string {
|
||||||
return time.Unix(1548854791, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
||||||
})
|
})
|
||||||
geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
|
geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
|
||||||
|
|
||||||
@@ -103,17 +103,17 @@ func TestAttachWelcome(t *testing.T) {
|
|||||||
"--http", "--http.port", httpPort,
|
"--http", "--http.port", httpPort,
|
||||||
"--ws", "--ws.port", wsPort)
|
"--ws", "--ws.port", wsPort)
|
||||||
t.Run("ipc", func(t *testing.T) {
|
t.Run("ipc", func(t *testing.T) {
|
||||||
waitForEndpoint(t, ipc, 3*time.Second)
|
waitForEndpoint(t, ipc, 4*time.Second)
|
||||||
testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs)
|
testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs)
|
||||||
})
|
})
|
||||||
t.Run("http", func(t *testing.T) {
|
t.Run("http", func(t *testing.T) {
|
||||||
endpoint := "http://127.0.0.1:" + httpPort
|
endpoint := "http://127.0.0.1:" + httpPort
|
||||||
waitForEndpoint(t, endpoint, 3*time.Second)
|
waitForEndpoint(t, endpoint, 4*time.Second)
|
||||||
testAttachWelcome(t, geth, endpoint, httpAPIs)
|
testAttachWelcome(t, geth, endpoint, httpAPIs)
|
||||||
})
|
})
|
||||||
t.Run("ws", func(t *testing.T) {
|
t.Run("ws", func(t *testing.T) {
|
||||||
endpoint := "ws://127.0.0.1:" + wsPort
|
endpoint := "ws://127.0.0.1:" + wsPort
|
||||||
waitForEndpoint(t, endpoint, 3*time.Second)
|
waitForEndpoint(t, endpoint, 4*time.Second)
|
||||||
testAttachWelcome(t, geth, endpoint, httpAPIs)
|
testAttachWelcome(t, geth, endpoint, httpAPIs)
|
||||||
})
|
})
|
||||||
geth.Kill()
|
geth.Kill()
|
||||||
@@ -131,7 +131,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
|
|||||||
attach.SetTemplateFunc("gover", runtime.Version)
|
attach.SetTemplateFunc("gover", runtime.Version)
|
||||||
attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") })
|
||||||
attach.SetTemplateFunc("niltime", func() string {
|
attach.SetTemplateFunc("niltime", func() string {
|
||||||
return time.Unix(1548854791, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
return time.Unix(1695902100, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)")
|
||||||
})
|
})
|
||||||
attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
|
attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
|
||||||
attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
|
attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
|
||||||
|
|||||||
@@ -246,11 +246,18 @@ func removeDB(ctx *cli.Context) error {
|
|||||||
ancientDir = config.Node.ResolvePath(ancientDir)
|
ancientDir = config.Node.ResolvePath(ancientDir)
|
||||||
}
|
}
|
||||||
// Delete state data
|
// Delete state data
|
||||||
statePaths := []string{rootDir, filepath.Join(ancientDir, rawdb.StateFreezerName)}
|
statePaths := []string{
|
||||||
|
rootDir,
|
||||||
|
filepath.Join(ancientDir, rawdb.MerkleStateFreezerName),
|
||||||
|
filepath.Join(ancientDir, rawdb.VerkleStateFreezerName),
|
||||||
|
}
|
||||||
confirmAndRemoveDB(statePaths, "state data", ctx, removeStateDataFlag.Name)
|
confirmAndRemoveDB(statePaths, "state data", ctx, removeStateDataFlag.Name)
|
||||||
|
|
||||||
// Delete ancient chain
|
// Delete ancient chain
|
||||||
chainPaths := []string{filepath.Join(ancientDir, rawdb.ChainFreezerName)}
|
chainPaths := []string{filepath.Join(
|
||||||
|
ancientDir,
|
||||||
|
rawdb.ChainFreezerName,
|
||||||
|
)}
|
||||||
confirmAndRemoveDB(chainPaths, "ancient chain", ctx, removeChainDataFlag.Name)
|
confirmAndRemoveDB(chainPaths, "ancient chain", ctx, removeChainDataFlag.Name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -401,17 +408,13 @@ func checkStateContent(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func showLeveldbStats(db ethdb.KeyValueStater) {
|
func showDBStats(db ethdb.KeyValueStater) {
|
||||||
if stats, err := db.Stat("leveldb.stats"); err != nil {
|
stats, err := db.Stat()
|
||||||
|
if err != nil {
|
||||||
log.Warn("Failed to read database stats", "error", err)
|
log.Warn("Failed to read database stats", "error", err)
|
||||||
} else {
|
return
|
||||||
fmt.Println(stats)
|
|
||||||
}
|
|
||||||
if ioStats, err := db.Stat("leveldb.iostats"); err != nil {
|
|
||||||
log.Warn("Failed to read database iostats", "error", err)
|
|
||||||
} else {
|
|
||||||
fmt.Println(ioStats)
|
|
||||||
}
|
}
|
||||||
|
fmt.Println(stats)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbStats(ctx *cli.Context) error {
|
func dbStats(ctx *cli.Context) error {
|
||||||
@@ -421,7 +424,7 @@ func dbStats(ctx *cli.Context) error {
|
|||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
showLeveldbStats(db)
|
showDBStats(db)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +436,7 @@ func dbCompact(ctx *cli.Context) error {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
log.Info("Stats before compaction")
|
log.Info("Stats before compaction")
|
||||||
showLeveldbStats(db)
|
showDBStats(db)
|
||||||
|
|
||||||
log.Info("Triggering compaction")
|
log.Info("Triggering compaction")
|
||||||
if err := db.Compact(nil, nil); err != nil {
|
if err := db.Compact(nil, nil); err != nil {
|
||||||
@@ -441,7 +444,7 @@ func dbCompact(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info("Stats after compaction")
|
log.Info("Stats after compaction")
|
||||||
showLeveldbStats(db)
|
showDBStats(db)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ import (
|
|||||||
// TestExport does a basic test of "geth export", exporting the test-genesis.
|
// TestExport does a basic test of "geth export", exporting the test-genesis.
|
||||||
func TestExport(t *testing.T) {
|
func TestExport(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
outfile := fmt.Sprintf("%v/testExport.out", os.TempDir())
|
outfile := fmt.Sprintf("%v/testExport.out", t.TempDir())
|
||||||
defer os.Remove(outfile)
|
|
||||||
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)
|
geth := runGeth(t, "--datadir", initGeth(t), "export", outfile)
|
||||||
geth.WaitExit()
|
geth.WaitExit()
|
||||||
if have, want := geth.ExitStatus(), 0; have != want {
|
if have, want := geth.ExitStatus(), 0; have != want {
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer readFile.Close()
|
||||||
wantLines := split(readFile)
|
wantLines := split(readFile)
|
||||||
haveLines := split(bytes.NewBuffer(haveB))
|
haveLines := split(bytes.NewBuffer(haveB))
|
||||||
for i, want := range wantLines {
|
for i, want := range wantLines {
|
||||||
@@ -109,6 +110,7 @@ func TestJsonLogging(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer readFile.Close()
|
||||||
wantLines := split(readFile)
|
wantLines := split(readFile)
|
||||||
haveLines := split(bytes.NewBuffer(haveB))
|
haveLines := split(bytes.NewBuffer(haveB))
|
||||||
for i, wantLine := range wantLines {
|
for i, wantLine := range wantLines {
|
||||||
@@ -199,9 +201,8 @@ func TestFileOut(t *testing.T) {
|
|||||||
var (
|
var (
|
||||||
have, want []byte
|
have, want []byte
|
||||||
err error
|
err error
|
||||||
path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63())
|
path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63())
|
||||||
)
|
)
|
||||||
t.Cleanup(func() { os.Remove(path) })
|
|
||||||
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil {
|
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "logtest"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -220,9 +221,8 @@ func TestRotatingFileOut(t *testing.T) {
|
|||||||
var (
|
var (
|
||||||
have, want []byte
|
have, want []byte
|
||||||
err error
|
err error
|
||||||
path = fmt.Sprintf("%s/test_file_out-%d", os.TempDir(), rand.Int63())
|
path = fmt.Sprintf("%s/test_file_out-%d", t.TempDir(), rand.Int63())
|
||||||
)
|
)
|
||||||
t.Cleanup(func() { os.Remove(path) })
|
|
||||||
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil {
|
if want, err = runSelf(fmt.Sprintf("--log.file=%s", path), "--log.rotate", "logtest"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,9 +288,6 @@ func main() {
|
|||||||
func prepare(ctx *cli.Context) {
|
func prepare(ctx *cli.Context) {
|
||||||
// If we're running a known preset, log it for convenience.
|
// If we're running a known preset, log it for convenience.
|
||||||
switch {
|
switch {
|
||||||
case ctx.IsSet(utils.GoerliFlag.Name):
|
|
||||||
log.Info("Starting Geth on Görli testnet...")
|
|
||||||
|
|
||||||
case ctx.IsSet(utils.SepoliaFlag.Name):
|
case ctx.IsSet(utils.SepoliaFlag.Name):
|
||||||
log.Info("Starting Geth on Sepolia testnet...")
|
log.Info("Starting Geth on Sepolia testnet...")
|
||||||
|
|
||||||
@@ -323,7 +320,6 @@ func prepare(ctx *cli.Context) {
|
|||||||
// Make sure we're not on any supported preconfigured testnet either
|
// Make sure we're not on any supported preconfigured testnet either
|
||||||
if !ctx.IsSet(utils.HoleskyFlag.Name) &&
|
if !ctx.IsSet(utils.HoleskyFlag.Name) &&
|
||||||
!ctx.IsSet(utils.SepoliaFlag.Name) &&
|
!ctx.IsSet(utils.SepoliaFlag.Name) &&
|
||||||
!ctx.IsSet(utils.GoerliFlag.Name) &&
|
|
||||||
!ctx.IsSet(utils.DeveloperFlag.Name) {
|
!ctx.IsSet(utils.DeveloperFlag.Name) {
|
||||||
// Nope, we're really on mainnet. Bump that cache up!
|
// Nope, we're really on mainnet. Bump that cache up!
|
||||||
log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096)
|
log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096)
|
||||||
@@ -359,8 +355,6 @@ func geth(ctx *cli.Context) error {
|
|||||||
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
|
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
|
||||||
// miner.
|
// miner.
|
||||||
func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) {
|
func startNode(ctx *cli.Context, stack *node.Node, isConsole bool) {
|
||||||
debug.Memsize.Add("node", stack)
|
|
||||||
|
|
||||||
// Start up the node itself
|
// Start up the node itself
|
||||||
utils.StartNode(ctx, stack, isConsole)
|
utils.StartNode(ctx, stack, isConsole)
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ data, and verifies that all snapshot storage data has a corresponding account.
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "inspect-account",
|
Name: "inspect-account",
|
||||||
Usage: "Check all snapshot layers for the a specific account",
|
Usage: "Check all snapshot layers for the specific account",
|
||||||
ArgsUsage: "<address | hash>",
|
ArgsUsage: "<address | hash>",
|
||||||
Action: checkAccount,
|
Action: checkAccount,
|
||||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
Flags: flags.Merge(utils.NetworkFlags, utils.DatabaseFlags),
|
||||||
@@ -544,7 +544,7 @@ func dumpState(ctx *cli.Context) error {
|
|||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
conf, root, err := parseDumpConfig(ctx, stack, db)
|
conf, root, err := parseDumpConfig(ctx, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
32
cmd/geth/testdata/vcheck/vulnerabilities.json
vendored
32
cmd/geth/testdata/vcheck/vulnerabilities.json
vendored
@@ -166,5 +166,37 @@
|
|||||||
"severity": "Low",
|
"severity": "Low",
|
||||||
"CVE": "CVE-2022-29177",
|
"CVE": "CVE-2022-29177",
|
||||||
"check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$"
|
"check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious p2p message",
|
||||||
|
"uid": "GETH-2023-01",
|
||||||
|
"summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.",
|
||||||
|
"description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.12.1",
|
||||||
|
"published": "2023-09-06",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2023-40591",
|
||||||
|
"check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious p2p message",
|
||||||
|
"uid": "GETH-2024-01",
|
||||||
|
"summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.",
|
||||||
|
"description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.13.15",
|
||||||
|
"published": "2024-05-06",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2024-32972",
|
||||||
|
"check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/gballet/go-verkle"
|
"github.com/ethereum/go-verkle"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,443 +0,0 @@
|
|||||||
// Copyright 2017 The go-ethereum Authors
|
|
||||||
// This file is part of go-ethereum.
|
|
||||||
//
|
|
||||||
// go-ethereum is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// go-ethereum 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 General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// p2psim provides a command-line client for a simulation HTTP API.
|
|
||||||
//
|
|
||||||
// Here is an example of creating a 2 node network with the first node
|
|
||||||
// connected to the second:
|
|
||||||
//
|
|
||||||
// $ p2psim node create
|
|
||||||
// Created node01
|
|
||||||
//
|
|
||||||
// $ p2psim node start node01
|
|
||||||
// Started node01
|
|
||||||
//
|
|
||||||
// $ p2psim node create
|
|
||||||
// Created node02
|
|
||||||
//
|
|
||||||
// $ p2psim node start node02
|
|
||||||
// Started node02
|
|
||||||
//
|
|
||||||
// $ p2psim node connect node01 node02
|
|
||||||
// Connected node01 to node02
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"text/tabwriter"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/simulations"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
var client *simulations.Client
|
|
||||||
|
|
||||||
var (
|
|
||||||
// global command flags
|
|
||||||
apiFlag = &cli.StringFlag{
|
|
||||||
Name: "api",
|
|
||||||
Value: "http://localhost:8888",
|
|
||||||
Usage: "simulation API URL",
|
|
||||||
EnvVars: []string{"P2PSIM_API_URL"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// events subcommand flags
|
|
||||||
currentFlag = &cli.BoolFlag{
|
|
||||||
Name: "current",
|
|
||||||
Usage: "get existing nodes and conns first",
|
|
||||||
}
|
|
||||||
filterFlag = &cli.StringFlag{
|
|
||||||
Name: "filter",
|
|
||||||
Value: "",
|
|
||||||
Usage: "message filter",
|
|
||||||
}
|
|
||||||
|
|
||||||
// node create subcommand flags
|
|
||||||
nameFlag = &cli.StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "",
|
|
||||||
Usage: "node name",
|
|
||||||
}
|
|
||||||
servicesFlag = &cli.StringFlag{
|
|
||||||
Name: "services",
|
|
||||||
Value: "",
|
|
||||||
Usage: "node services (comma separated)",
|
|
||||||
}
|
|
||||||
keyFlag = &cli.StringFlag{
|
|
||||||
Name: "key",
|
|
||||||
Value: "",
|
|
||||||
Usage: "node private key (hex encoded)",
|
|
||||||
}
|
|
||||||
|
|
||||||
// node rpc subcommand flags
|
|
||||||
subscribeFlag = &cli.BoolFlag{
|
|
||||||
Name: "subscribe",
|
|
||||||
Usage: "method is a subscription",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
app := flags.NewApp("devp2p simulation command-line client")
|
|
||||||
app.Flags = []cli.Flag{
|
|
||||||
apiFlag,
|
|
||||||
}
|
|
||||||
app.Before = func(ctx *cli.Context) error {
|
|
||||||
client = simulations.NewClient(ctx.String(apiFlag.Name))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
app.Commands = []*cli.Command{
|
|
||||||
{
|
|
||||||
Name: "show",
|
|
||||||
Usage: "show network information",
|
|
||||||
Action: showNetwork,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "events",
|
|
||||||
Usage: "stream network events",
|
|
||||||
Action: streamNetwork,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
currentFlag,
|
|
||||||
filterFlag,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "snapshot",
|
|
||||||
Usage: "create a network snapshot to stdout",
|
|
||||||
Action: createSnapshot,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "load",
|
|
||||||
Usage: "load a network snapshot from stdin",
|
|
||||||
Action: loadSnapshot,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "node",
|
|
||||||
Usage: "manage simulation nodes",
|
|
||||||
Action: listNodes,
|
|
||||||
Subcommands: []*cli.Command{
|
|
||||||
{
|
|
||||||
Name: "list",
|
|
||||||
Usage: "list nodes",
|
|
||||||
Action: listNodes,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "create",
|
|
||||||
Usage: "create a node",
|
|
||||||
Action: createNode,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
nameFlag,
|
|
||||||
servicesFlag,
|
|
||||||
keyFlag,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "show",
|
|
||||||
ArgsUsage: "<node>",
|
|
||||||
Usage: "show node information",
|
|
||||||
Action: showNode,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "start",
|
|
||||||
ArgsUsage: "<node>",
|
|
||||||
Usage: "start a node",
|
|
||||||
Action: startNode,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "stop",
|
|
||||||
ArgsUsage: "<node>",
|
|
||||||
Usage: "stop a node",
|
|
||||||
Action: stopNode,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "connect",
|
|
||||||
ArgsUsage: "<node> <peer>",
|
|
||||||
Usage: "connect a node to a peer node",
|
|
||||||
Action: connectNode,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "disconnect",
|
|
||||||
ArgsUsage: "<node> <peer>",
|
|
||||||
Usage: "disconnect a node from a peer node",
|
|
||||||
Action: disconnectNode,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "rpc",
|
|
||||||
ArgsUsage: "<node> <method> [<args>]",
|
|
||||||
Usage: "call a node RPC method",
|
|
||||||
Action: rpcNode,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
subscribeFlag,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func showNetwork(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
network, err := client.GetNetwork()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0)
|
|
||||||
defer w.Flush()
|
|
||||||
fmt.Fprintf(w, "NODES\t%d\n", len(network.Nodes))
|
|
||||||
fmt.Fprintf(w, "CONNS\t%d\n", len(network.Conns))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func streamNetwork(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
events := make(chan *simulations.Event)
|
|
||||||
sub, err := client.SubscribeNetwork(events, simulations.SubscribeOpts{
|
|
||||||
Current: ctx.Bool(currentFlag.Name),
|
|
||||||
Filter: ctx.String(filterFlag.Name),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer sub.Unsubscribe()
|
|
||||||
enc := json.NewEncoder(ctx.App.Writer)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case event := <-events:
|
|
||||||
if err := enc.Encode(event); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case err := <-sub.Err():
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func createSnapshot(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
snap, err := client.CreateSnapshot()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return json.NewEncoder(os.Stdout).Encode(snap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadSnapshot(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
snap := &simulations.Snapshot{}
|
|
||||||
if err := json.NewDecoder(os.Stdin).Decode(snap); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return client.LoadSnapshot(snap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listNodes(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodes, err := client.GetNodes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0)
|
|
||||||
defer w.Flush()
|
|
||||||
fmt.Fprintf(w, "NAME\tPROTOCOLS\tID\n")
|
|
||||||
for _, node := range nodes {
|
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\n", node.Name, strings.Join(protocolList(node), ","), node.ID)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func protocolList(node *p2p.NodeInfo) []string {
|
|
||||||
protos := make([]string, 0, len(node.Protocols))
|
|
||||||
for name := range node.Protocols {
|
|
||||||
protos = append(protos, name)
|
|
||||||
}
|
|
||||||
return protos
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNode(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 0 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
config := adapters.RandomNodeConfig()
|
|
||||||
config.Name = ctx.String(nameFlag.Name)
|
|
||||||
if key := ctx.String(keyFlag.Name); key != "" {
|
|
||||||
privKey, err := crypto.HexToECDSA(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
config.ID = enode.PubkeyToIDV4(&privKey.PublicKey)
|
|
||||||
config.PrivateKey = privKey
|
|
||||||
}
|
|
||||||
if services := ctx.String(servicesFlag.Name); services != "" {
|
|
||||||
config.Lifecycles = strings.Split(services, ",")
|
|
||||||
}
|
|
||||||
node, err := client.CreateNode(config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(ctx.App.Writer, "Created", node.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func showNode(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 1 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodeName := ctx.Args().First()
|
|
||||||
node, err := client.GetNode(nodeName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w := tabwriter.NewWriter(ctx.App.Writer, 1, 2, 2, ' ', 0)
|
|
||||||
defer w.Flush()
|
|
||||||
fmt.Fprintf(w, "NAME\t%s\n", node.Name)
|
|
||||||
fmt.Fprintf(w, "PROTOCOLS\t%s\n", strings.Join(protocolList(node), ","))
|
|
||||||
fmt.Fprintf(w, "ID\t%s\n", node.ID)
|
|
||||||
fmt.Fprintf(w, "ENODE\t%s\n", node.Enode)
|
|
||||||
for name, proto := range node.Protocols {
|
|
||||||
fmt.Fprintln(w)
|
|
||||||
fmt.Fprintf(w, "--- PROTOCOL INFO: %s\n", name)
|
|
||||||
fmt.Fprintf(w, "%v\n", proto)
|
|
||||||
fmt.Fprintf(w, "---\n")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func startNode(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 1 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodeName := ctx.Args().First()
|
|
||||||
if err := client.StartNode(nodeName); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(ctx.App.Writer, "Started", nodeName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopNode(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 1 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodeName := ctx.Args().First()
|
|
||||||
if err := client.StopNode(nodeName); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(ctx.App.Writer, "Stopped", nodeName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func connectNode(ctx *cli.Context) error {
|
|
||||||
if ctx.NArg() != 2 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
args := ctx.Args()
|
|
||||||
nodeName := args.Get(0)
|
|
||||||
peerName := args.Get(1)
|
|
||||||
if err := client.ConnectNode(nodeName, peerName); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(ctx.App.Writer, "Connected", nodeName, "to", peerName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func disconnectNode(ctx *cli.Context) error {
|
|
||||||
args := ctx.Args()
|
|
||||||
if args.Len() != 2 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodeName := args.Get(0)
|
|
||||||
peerName := args.Get(1)
|
|
||||||
if err := client.DisconnectNode(nodeName, peerName); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(ctx.App.Writer, "Disconnected", nodeName, "from", peerName)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func rpcNode(ctx *cli.Context) error {
|
|
||||||
args := ctx.Args()
|
|
||||||
if args.Len() < 2 {
|
|
||||||
return cli.ShowCommandHelp(ctx, ctx.Command.Name)
|
|
||||||
}
|
|
||||||
nodeName := args.Get(0)
|
|
||||||
method := args.Get(1)
|
|
||||||
rpcClient, err := client.RPCClient(context.Background(), nodeName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if ctx.Bool(subscribeFlag.Name) {
|
|
||||||
return rpcSubscribe(rpcClient, ctx.App.Writer, method, args.Slice()[3:]...)
|
|
||||||
}
|
|
||||||
var result interface{}
|
|
||||||
params := make([]interface{}, len(args.Slice()[3:]))
|
|
||||||
for i, v := range args.Slice()[3:] {
|
|
||||||
params[i] = v
|
|
||||||
}
|
|
||||||
if err := rpcClient.Call(&result, method, params...); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return json.NewEncoder(ctx.App.Writer).Encode(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func rpcSubscribe(client *rpc.Client, out io.Writer, method string, args ...string) error {
|
|
||||||
namespace, method, _ := strings.Cut(method, "_")
|
|
||||||
ch := make(chan interface{})
|
|
||||||
subArgs := make([]interface{}, len(args)+1)
|
|
||||||
subArgs[0] = method
|
|
||||||
for i, v := range args {
|
|
||||||
subArgs[i+1] = v
|
|
||||||
}
|
|
||||||
sub, err := client.Subscribe(context.Background(), namespace, ch, subArgs...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer sub.Unsubscribe()
|
|
||||||
enc := json.NewEncoder(out)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case v := <-ch:
|
|
||||||
if err := enc.Encode(v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case err := <-sub.Err():
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -262,7 +262,6 @@ func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, networ
|
|||||||
start = time.Now()
|
start = time.Now()
|
||||||
reported = time.Now()
|
reported = time.Now()
|
||||||
imported = 0
|
imported = 0
|
||||||
forker = core.NewForkChoice(chain, nil)
|
|
||||||
h = sha256.New()
|
h = sha256.New()
|
||||||
buf = bytes.NewBuffer(nil)
|
buf = bytes.NewBuffer(nil)
|
||||||
)
|
)
|
||||||
@@ -305,7 +304,7 @@ func ImportHistory(chain *core.BlockChain, db ethdb.Database, dir string, networ
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error reading receipts %d: %w", it.Number(), err)
|
return fmt.Errorf("error reading receipts %d: %w", it.Number(), err)
|
||||||
}
|
}
|
||||||
if status, err := chain.HeaderChain().InsertHeaderChain([]*types.Header{block.Header()}, start, forker); err != nil {
|
if status, err := chain.HeaderChain().InsertHeaderChain([]*types.Header{block.Header()}, start); err != nil {
|
||||||
return fmt.Errorf("error inserting header %d: %w", it.Number(), err)
|
return fmt.Errorf("error inserting header %d: %w", it.Number(), err)
|
||||||
} else if status != core.CanonStatTy {
|
} else if status != core.CanonStatTy {
|
||||||
return fmt.Errorf("error inserting header %d, not canon: %v", it.Number(), status)
|
return fmt.Errorf("error inserting header %d, not canon: %v", it.Number(), status)
|
||||||
|
|||||||
@@ -29,18 +29,12 @@ import (
|
|||||||
|
|
||||||
// TestExport does basic sanity checks on the export/import functionality
|
// TestExport does basic sanity checks on the export/import functionality
|
||||||
func TestExport(t *testing.T) {
|
func TestExport(t *testing.T) {
|
||||||
f := fmt.Sprintf("%v/tempdump", os.TempDir())
|
f := fmt.Sprintf("%v/tempdump", t.TempDir())
|
||||||
defer func() {
|
|
||||||
os.Remove(f)
|
|
||||||
}()
|
|
||||||
testExport(t, f)
|
testExport(t, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExportGzip(t *testing.T) {
|
func TestExportGzip(t *testing.T) {
|
||||||
f := fmt.Sprintf("%v/tempdump.gz", os.TempDir())
|
f := fmt.Sprintf("%v/tempdump.gz", t.TempDir())
|
||||||
defer func() {
|
|
||||||
os.Remove(f)
|
|
||||||
}()
|
|
||||||
testExport(t, f)
|
testExport(t, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,20 +93,14 @@ func testExport(t *testing.T, f string) {
|
|||||||
|
|
||||||
// TestDeletionExport tests if the deletion markers can be exported/imported correctly
|
// TestDeletionExport tests if the deletion markers can be exported/imported correctly
|
||||||
func TestDeletionExport(t *testing.T) {
|
func TestDeletionExport(t *testing.T) {
|
||||||
f := fmt.Sprintf("%v/tempdump", os.TempDir())
|
f := fmt.Sprintf("%v/tempdump", t.TempDir())
|
||||||
defer func() {
|
|
||||||
os.Remove(f)
|
|
||||||
}()
|
|
||||||
testDeletion(t, f)
|
testDeletion(t, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDeletionExportGzip tests if the deletion markers can be exported/imported
|
// TestDeletionExportGzip tests if the deletion markers can be exported/imported
|
||||||
// correctly with gz compression.
|
// correctly with gz compression.
|
||||||
func TestDeletionExportGzip(t *testing.T) {
|
func TestDeletionExportGzip(t *testing.T) {
|
||||||
f := fmt.Sprintf("%v/tempdump.gz", os.TempDir())
|
f := fmt.Sprintf("%v/tempdump.gz", t.TempDir())
|
||||||
defer func() {
|
|
||||||
os.Remove(f)
|
|
||||||
}()
|
|
||||||
testDeletion(t, f)
|
testDeletion(t, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,10 +159,7 @@ func testDeletion(t *testing.T, f string) {
|
|||||||
// TestImportFutureFormat tests that we reject unsupported future versions.
|
// TestImportFutureFormat tests that we reject unsupported future versions.
|
||||||
func TestImportFutureFormat(t *testing.T) {
|
func TestImportFutureFormat(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
f := fmt.Sprintf("%v/tempdump-future", os.TempDir())
|
f := fmt.Sprintf("%v/tempdump-future", t.TempDir())
|
||||||
defer func() {
|
|
||||||
os.Remove(f)
|
|
||||||
}()
|
|
||||||
fh, err := os.OpenFile(f, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
fh, err := os.OpenFile(f, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/fdlimit"
|
"github.com/ethereum/go-ethereum/common/fdlimit"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/txpool/blobpool"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
|
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
@@ -133,7 +134,7 @@ var (
|
|||||||
}
|
}
|
||||||
NetworkIdFlag = &cli.Uint64Flag{
|
NetworkIdFlag = &cli.Uint64Flag{
|
||||||
Name: "networkid",
|
Name: "networkid",
|
||||||
Usage: "Explicitly set network id (integer)(For testnets: use --goerli, --sepolia, --holesky instead)",
|
Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky instead)",
|
||||||
Value: ethconfig.Defaults.NetworkId,
|
Value: ethconfig.Defaults.NetworkId,
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
@@ -142,11 +143,6 @@ var (
|
|||||||
Usage: "Ethereum mainnet",
|
Usage: "Ethereum mainnet",
|
||||||
Category: flags.EthCategory,
|
Category: flags.EthCategory,
|
||||||
}
|
}
|
||||||
GoerliFlag = &cli.BoolFlag{
|
|
||||||
Name: "goerli",
|
|
||||||
Usage: "Görli network: pre-configured proof-of-authority test network",
|
|
||||||
Category: flags.EthCategory,
|
|
||||||
}
|
|
||||||
SepoliaFlag = &cli.BoolFlag{
|
SepoliaFlag = &cli.BoolFlag{
|
||||||
Name: "sepolia",
|
Name: "sepolia",
|
||||||
Usage: "Sepolia network: pre-configured proof-of-work test network",
|
Usage: "Sepolia network: pre-configured proof-of-work test network",
|
||||||
@@ -291,7 +287,7 @@ var (
|
|||||||
}
|
}
|
||||||
BeaconApiHeaderFlag = &cli.StringSliceFlag{
|
BeaconApiHeaderFlag = &cli.StringSliceFlag{
|
||||||
Name: "beacon.api.header",
|
Name: "beacon.api.header",
|
||||||
Usage: "Pass custom HTTP header fields to the emote beacon node API in \"key:value\" format. This flag can be given multiple times.",
|
Usage: "Pass custom HTTP header fields to the remote beacon node API in \"key:value\" format. This flag can be given multiple times.",
|
||||||
Category: flags.BeaconCategory,
|
Category: flags.BeaconCategory,
|
||||||
}
|
}
|
||||||
BeaconThresholdFlag = &cli.IntFlag{
|
BeaconThresholdFlag = &cli.IntFlag{
|
||||||
@@ -806,8 +802,9 @@ var (
|
|||||||
DiscoveryV5Flag = &cli.BoolFlag{
|
DiscoveryV5Flag = &cli.BoolFlag{
|
||||||
Name: "discovery.v5",
|
Name: "discovery.v5",
|
||||||
Aliases: []string{"discv5"},
|
Aliases: []string{"discv5"},
|
||||||
Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism",
|
Usage: "Enables the V5 discovery mechanism",
|
||||||
Category: flags.NetworkingCategory,
|
Category: flags.NetworkingCategory,
|
||||||
|
Value: true,
|
||||||
}
|
}
|
||||||
NetrestrictFlag = &cli.StringFlag{
|
NetrestrictFlag = &cli.StringFlag{
|
||||||
Name: "netrestrict",
|
Name: "netrestrict",
|
||||||
@@ -959,7 +956,6 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
|
|||||||
var (
|
var (
|
||||||
// TestnetFlags is the flag group of all built-in supported testnets.
|
// TestnetFlags is the flag group of all built-in supported testnets.
|
||||||
TestnetFlags = []cli.Flag{
|
TestnetFlags = []cli.Flag{
|
||||||
GoerliFlag,
|
|
||||||
SepoliaFlag,
|
SepoliaFlag,
|
||||||
HoleskyFlag,
|
HoleskyFlag,
|
||||||
}
|
}
|
||||||
@@ -982,9 +978,6 @@ var (
|
|||||||
// then a subdirectory of the specified datadir will be used.
|
// then a subdirectory of the specified datadir will be used.
|
||||||
func MakeDataDir(ctx *cli.Context) string {
|
func MakeDataDir(ctx *cli.Context) string {
|
||||||
if path := ctx.String(DataDirFlag.Name); path != "" {
|
if path := ctx.String(DataDirFlag.Name); path != "" {
|
||||||
if ctx.Bool(GoerliFlag.Name) {
|
|
||||||
return filepath.Join(path, "goerli")
|
|
||||||
}
|
|
||||||
if ctx.Bool(SepoliaFlag.Name) {
|
if ctx.Bool(SepoliaFlag.Name) {
|
||||||
return filepath.Join(path, "sepolia")
|
return filepath.Join(path, "sepolia")
|
||||||
}
|
}
|
||||||
@@ -1036,7 +1029,7 @@ func setNodeUserIdent(ctx *cli.Context, cfg *node.Config) {
|
|||||||
//
|
//
|
||||||
// 1. --bootnodes flag
|
// 1. --bootnodes flag
|
||||||
// 2. Config file
|
// 2. Config file
|
||||||
// 3. Network preset flags (e.g. --goerli)
|
// 3. Network preset flags (e.g. --holesky)
|
||||||
// 4. default to mainnet nodes
|
// 4. default to mainnet nodes
|
||||||
func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
|
func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
|
||||||
urls := params.MainnetBootnodes
|
urls := params.MainnetBootnodes
|
||||||
@@ -1051,8 +1044,6 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
|
|||||||
urls = params.HoleskyBootnodes
|
urls = params.HoleskyBootnodes
|
||||||
case ctx.Bool(SepoliaFlag.Name):
|
case ctx.Bool(SepoliaFlag.Name):
|
||||||
urls = params.SepoliaBootnodes
|
urls = params.SepoliaBootnodes
|
||||||
case ctx.Bool(GoerliFlag.Name):
|
|
||||||
urls = params.GoerliBootnodes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg.BootstrapNodes = mustParseBootnodes(urls)
|
cfg.BootstrapNodes = mustParseBootnodes(urls)
|
||||||
@@ -1316,7 +1307,6 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error
|
|||||||
func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if ctx.IsSet(MinerEtherbaseFlag.Name) {
|
if ctx.IsSet(MinerEtherbaseFlag.Name) {
|
||||||
log.Warn("Option --miner.etherbase is deprecated as the etherbase is set by the consensus client post-merge")
|
log.Warn("Option --miner.etherbase is deprecated as the etherbase is set by the consensus client post-merge")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if !ctx.IsSet(MinerPendingFeeRecipientFlag.Name) {
|
if !ctx.IsSet(MinerPendingFeeRecipientFlag.Name) {
|
||||||
return
|
return
|
||||||
@@ -1478,8 +1468,6 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) {
|
|||||||
cfg.DataDir = ctx.String(DataDirFlag.Name)
|
cfg.DataDir = ctx.String(DataDirFlag.Name)
|
||||||
case ctx.Bool(DeveloperFlag.Name):
|
case ctx.Bool(DeveloperFlag.Name):
|
||||||
cfg.DataDir = "" // unless explicitly requested, use memory databases
|
cfg.DataDir = "" // unless explicitly requested, use memory databases
|
||||||
case ctx.Bool(GoerliFlag.Name) && cfg.DataDir == node.DefaultDataDir():
|
|
||||||
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
|
|
||||||
case ctx.Bool(SepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir():
|
case ctx.Bool(SepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir():
|
||||||
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
|
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
|
||||||
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
|
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
|
||||||
@@ -1545,6 +1533,18 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setBlobPool(ctx *cli.Context, cfg *blobpool.Config) {
|
||||||
|
if ctx.IsSet(BlobPoolDataDirFlag.Name) {
|
||||||
|
cfg.Datadir = ctx.String(BlobPoolDataDirFlag.Name)
|
||||||
|
}
|
||||||
|
if ctx.IsSet(BlobPoolDataCapFlag.Name) {
|
||||||
|
cfg.Datacap = ctx.Uint64(BlobPoolDataCapFlag.Name)
|
||||||
|
}
|
||||||
|
if ctx.IsSet(BlobPoolPriceBumpFlag.Name) {
|
||||||
|
cfg.PriceBump = ctx.Uint64(BlobPoolPriceBumpFlag.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setMiner(ctx *cli.Context, cfg *miner.Config) {
|
func setMiner(ctx *cli.Context, cfg *miner.Config) {
|
||||||
if ctx.Bool(MiningEnabledFlag.Name) {
|
if ctx.Bool(MiningEnabledFlag.Name) {
|
||||||
log.Warn("The flag --mine is deprecated and will be removed")
|
log.Warn("The flag --mine is deprecated and will be removed")
|
||||||
@@ -1639,13 +1639,14 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
|
|||||||
// SetEthConfig applies eth-related command line flags to the config.
|
// SetEthConfig applies eth-related command line flags to the config.
|
||||||
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
// Avoid conflicting network flags
|
// Avoid conflicting network flags
|
||||||
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag)
|
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag)
|
||||||
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
|
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
|
||||||
|
|
||||||
// Set configurations from CLI flags
|
// Set configurations from CLI flags
|
||||||
setEtherbase(ctx, cfg)
|
setEtherbase(ctx, cfg)
|
||||||
setGPO(ctx, &cfg.GPO)
|
setGPO(ctx, &cfg.GPO)
|
||||||
setTxPool(ctx, &cfg.TxPool)
|
setTxPool(ctx, &cfg.TxPool)
|
||||||
|
setBlobPool(ctx, &cfg.BlobPool)
|
||||||
setMiner(ctx, &cfg.Miner)
|
setMiner(ctx, &cfg.Miner)
|
||||||
setRequiredBlocks(ctx, cfg)
|
setRequiredBlocks(ctx, cfg)
|
||||||
setLes(ctx, cfg)
|
setLes(ctx, cfg)
|
||||||
@@ -1805,12 +1806,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
}
|
}
|
||||||
cfg.Genesis = core.DefaultSepoliaGenesisBlock()
|
cfg.Genesis = core.DefaultSepoliaGenesisBlock()
|
||||||
SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash)
|
SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash)
|
||||||
case ctx.Bool(GoerliFlag.Name):
|
|
||||||
if !ctx.IsSet(NetworkIdFlag.Name) {
|
|
||||||
cfg.NetworkId = 5
|
|
||||||
}
|
|
||||||
cfg.Genesis = core.DefaultGoerliGenesisBlock()
|
|
||||||
SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
|
|
||||||
case ctx.Bool(DeveloperFlag.Name):
|
case ctx.Bool(DeveloperFlag.Name):
|
||||||
if !ctx.IsSet(NetworkIdFlag.Name) {
|
if !ctx.IsSet(NetworkIdFlag.Name) {
|
||||||
cfg.NetworkId = 1337
|
cfg.NetworkId = 1337
|
||||||
@@ -1872,13 +1867,15 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
Fatalf("Could not read genesis from database: %v", err)
|
Fatalf("Could not read genesis from database: %v", err)
|
||||||
}
|
}
|
||||||
if !genesis.Config.TerminalTotalDifficultyPassed {
|
if !genesis.Config.TerminalTotalDifficultyPassed {
|
||||||
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficultyPassed must be true in developer mode")
|
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficultyPassed must be true")
|
||||||
}
|
}
|
||||||
if genesis.Config.TerminalTotalDifficulty == nil {
|
if genesis.Config.TerminalTotalDifficulty == nil {
|
||||||
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be specified.")
|
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be specified")
|
||||||
|
} else if genesis.Config.TerminalTotalDifficulty.Cmp(big.NewInt(0)) != 0 {
|
||||||
|
Fatalf("Bad developer-mode genesis configuration: terminalTotalDifficulty must be 0")
|
||||||
}
|
}
|
||||||
if genesis.Difficulty.Cmp(genesis.Config.TerminalTotalDifficulty) != 1 {
|
if genesis.Difficulty.Cmp(big.NewInt(0)) != 0 {
|
||||||
Fatalf("Bad developer-mode genesis configuration: genesis block difficulty must be > terminalTotalDifficulty")
|
Fatalf("Bad developer-mode genesis configuration: difficulty must be 0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chaindb.Close()
|
chaindb.Close()
|
||||||
@@ -1928,7 +1925,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) {
|
|||||||
|
|
||||||
// RegisterEthService adds an Ethereum client to the stack.
|
// RegisterEthService adds an Ethereum client to the stack.
|
||||||
// The second return value is the full node instance.
|
// The second return value is the full node instance.
|
||||||
func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend, *eth.Ethereum) {
|
func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (*eth.EthAPIBackend, *eth.Ethereum) {
|
||||||
backend, err := eth.New(stack, cfg)
|
backend, err := eth.New(stack, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to register the Ethereum service: %v", err)
|
Fatalf("Failed to register the Ethereum service: %v", err)
|
||||||
@@ -1938,7 +1935,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node.
|
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node.
|
||||||
func RegisterEthStatsService(stack *node.Node, backend ethapi.Backend, url string) {
|
func RegisterEthStatsService(stack *node.Node, backend *eth.EthAPIBackend, url string) {
|
||||||
if err := ethstats.New(stack, backend, backend.Engine(), url); err != nil {
|
if err := ethstats.New(stack, backend, backend.Engine(), url); err != nil {
|
||||||
Fatalf("Failed to register the Ethereum Stats service: %v", err)
|
Fatalf("Failed to register the Ethereum Stats service: %v", err)
|
||||||
}
|
}
|
||||||
@@ -2064,8 +2061,6 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
chainDb = remotedb.New(client)
|
chainDb = remotedb.New(client)
|
||||||
case ctx.String(SyncModeFlag.Name) == "light":
|
|
||||||
chainDb, err = stack.OpenDatabase("lightchaindata", cache, handles, "", readonly)
|
|
||||||
default:
|
default:
|
||||||
chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly)
|
chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly)
|
||||||
}
|
}
|
||||||
@@ -2130,8 +2125,6 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
|
|||||||
genesis = core.DefaultHoleskyGenesisBlock()
|
genesis = core.DefaultHoleskyGenesisBlock()
|
||||||
case ctx.Bool(SepoliaFlag.Name):
|
case ctx.Bool(SepoliaFlag.Name):
|
||||||
genesis = core.DefaultSepoliaGenesisBlock()
|
genesis = core.DefaultSepoliaGenesisBlock()
|
||||||
case ctx.Bool(GoerliFlag.Name):
|
|
||||||
genesis = core.DefaultGoerliGenesisBlock()
|
|
||||||
case ctx.Bool(DeveloperFlag.Name):
|
case ctx.Bool(DeveloperFlag.Name):
|
||||||
Fatalf("Developer chains are ephemeral")
|
Fatalf("Developer chains are ephemeral")
|
||||||
}
|
}
|
||||||
@@ -2188,7 +2181,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
|||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
||||||
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
|
vmcfg := vm.Config{
|
||||||
|
EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name),
|
||||||
|
}
|
||||||
if ctx.IsSet(VMTraceFlag.Name) {
|
if ctx.IsSet(VMTraceFlag.Name) {
|
||||||
if name := ctx.String(VMTraceFlag.Name); name != "" {
|
if name := ctx.String(VMTraceFlag.Name); name != "" {
|
||||||
var config json.RawMessage
|
var config json.RawMessage
|
||||||
@@ -2203,7 +2198,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Disable transaction indexing/unindexing by default.
|
// Disable transaction indexing/unindexing by default.
|
||||||
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil, nil)
|
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Can't create BlockChain: %v", err)
|
Fatalf("Can't create BlockChain: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,25 +92,21 @@ var (
|
|||||||
LightServeFlag = &cli.IntFlag{
|
LightServeFlag = &cli.IntFlag{
|
||||||
Name: "light.serve",
|
Name: "light.serve",
|
||||||
Usage: "Maximum percentage of time allowed for serving LES requests (deprecated)",
|
Usage: "Maximum percentage of time allowed for serving LES requests (deprecated)",
|
||||||
Value: ethconfig.Defaults.LightServ,
|
|
||||||
Category: flags.DeprecatedCategory,
|
Category: flags.DeprecatedCategory,
|
||||||
}
|
}
|
||||||
LightIngressFlag = &cli.IntFlag{
|
LightIngressFlag = &cli.IntFlag{
|
||||||
Name: "light.ingress",
|
Name: "light.ingress",
|
||||||
Usage: "Incoming bandwidth limit for serving light clients (deprecated)",
|
Usage: "Incoming bandwidth limit for serving light clients (deprecated)",
|
||||||
Value: ethconfig.Defaults.LightIngress,
|
|
||||||
Category: flags.DeprecatedCategory,
|
Category: flags.DeprecatedCategory,
|
||||||
}
|
}
|
||||||
LightEgressFlag = &cli.IntFlag{
|
LightEgressFlag = &cli.IntFlag{
|
||||||
Name: "light.egress",
|
Name: "light.egress",
|
||||||
Usage: "Outgoing bandwidth limit for serving light clients (deprecated)",
|
Usage: "Outgoing bandwidth limit for serving light clients (deprecated)",
|
||||||
Value: ethconfig.Defaults.LightEgress,
|
|
||||||
Category: flags.DeprecatedCategory,
|
Category: flags.DeprecatedCategory,
|
||||||
}
|
}
|
||||||
LightMaxPeersFlag = &cli.IntFlag{
|
LightMaxPeersFlag = &cli.IntFlag{
|
||||||
Name: "light.maxpeers",
|
Name: "light.maxpeers",
|
||||||
Usage: "Maximum number of light clients to serve, or light servers to attach to (deprecated)",
|
Usage: "Maximum number of light clients to serve, or light servers to attach to (deprecated)",
|
||||||
Value: ethconfig.Defaults.LightPeers,
|
|
||||||
Category: flags.DeprecatedCategory,
|
Category: flags.DeprecatedCategory,
|
||||||
}
|
}
|
||||||
LightNoPruneFlag = &cli.BoolFlag{
|
LightNoPruneFlag = &cli.BoolFlag{
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Initialize BlockChain.
|
// Initialize BlockChain.
|
||||||
chain, err := core.NewBlockChain(db, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
|
chain, err := core.NewBlockChain(db, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize chain: %v", err)
|
t.Fatalf("unable to initialize chain: %v", err)
|
||||||
}
|
}
|
||||||
@@ -162,8 +162,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now import Era.
|
// Now import Era.
|
||||||
freezer := t.TempDir()
|
db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
|
||||||
db2, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -172,7 +171,7 @@ func TestHistoryImportAndExport(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
genesis.MustCommit(db2, triedb.NewDatabase(db, triedb.HashDefaults))
|
genesis.MustCommit(db2, triedb.NewDatabase(db, triedb.HashDefaults))
|
||||||
imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
|
imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize chain: %v", err)
|
t.Fatalf("unable to initialize chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 {
|
|||||||
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
|
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
|
||||||
// quoted decimal strings.
|
// quoted decimal strings.
|
||||||
func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error {
|
func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error {
|
||||||
if len(input) > 0 && input[0] == '"' {
|
if len(input) > 1 && input[0] == '"' {
|
||||||
input = input[1 : len(input)-1]
|
input = input[1 : len(input)-1]
|
||||||
}
|
}
|
||||||
return i.UnmarshalText(input)
|
return i.UnmarshalText(input)
|
||||||
|
|||||||
@@ -180,9 +180,9 @@ func BenchmarkByteAtOld(b *testing.B) {
|
|||||||
func TestReadBits(t *testing.T) {
|
func TestReadBits(t *testing.T) {
|
||||||
check := func(input string) {
|
check := func(input string) {
|
||||||
want, _ := hex.DecodeString(input)
|
want, _ := hex.DecodeString(input)
|
||||||
int, _ := new(big.Int).SetString(input, 16)
|
n, _ := new(big.Int).SetString(input, 16)
|
||||||
buf := make([]byte, len(want))
|
buf := make([]byte, len(want))
|
||||||
ReadBits(int, buf)
|
ReadBits(n, buf)
|
||||||
if !bytes.Equal(buf, want) {
|
if !bytes.Equal(buf, want) {
|
||||||
t.Errorf("have: %x\nwant: %x", buf, want)
|
t.Errorf("have: %x\nwant: %x", buf, want)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ type HexOrDecimal64 uint64
|
|||||||
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
|
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
|
||||||
// quoted decimal strings.
|
// quoted decimal strings.
|
||||||
func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error {
|
func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error {
|
||||||
if len(input) > 0 && input[0] == '"' {
|
if len(input) > 1 && input[0] == '"' {
|
||||||
input = input[1 : len(input)-1]
|
input = input[1 : len(input)-1]
|
||||||
}
|
}
|
||||||
return i.UnmarshalText(input)
|
return i.UnmarshalText(input)
|
||||||
@@ -54,11 +54,11 @@ func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error {
|
|||||||
|
|
||||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||||
func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
|
func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
|
||||||
int, ok := ParseUint64(string(input))
|
n, ok := ParseUint64(string(input))
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("invalid hex or decimal integer %q", input)
|
return fmt.Errorf("invalid hex or decimal integer %q", input)
|
||||||
}
|
}
|
||||||
*i = HexOrDecimal64(int)
|
*i = HexOrDecimal64(n)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ func (d *Decimal) UnmarshalJSON(input []byte) error {
|
|||||||
if !isString(input) {
|
if !isString(input) {
|
||||||
return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))}
|
return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))}
|
||||||
}
|
}
|
||||||
if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil {
|
if i, err := strconv.ParseUint(string(input[1:len(input)-1]), 10, 64); err == nil {
|
||||||
*d = Decimal(i)
|
*d = Decimal(i)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -595,3 +596,29 @@ func BenchmarkPrettyDuration(b *testing.B) {
|
|||||||
}
|
}
|
||||||
b.Logf("Post %s", a)
|
b.Logf("Post %s", a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecimalUnmarshalJSON(t *testing.T) {
|
||||||
|
// These should error
|
||||||
|
for _, tc := range []string{``, `"`, `""`, `"-1"`} {
|
||||||
|
if err := new(Decimal).UnmarshalJSON([]byte(tc)); err == nil {
|
||||||
|
t.Errorf("input %s should cause error", tc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// These should succeed
|
||||||
|
for _, tc := range []struct {
|
||||||
|
input string
|
||||||
|
want uint64
|
||||||
|
}{
|
||||||
|
{`"0"`, 0},
|
||||||
|
{`"9223372036854775807"`, math.MaxInt64},
|
||||||
|
{`"18446744073709551615"`, math.MaxUint64},
|
||||||
|
} {
|
||||||
|
have := new(Decimal)
|
||||||
|
if err := have.UnmarshalJSON([]byte(tc.input)); err != nil {
|
||||||
|
t.Errorf("input %q triggered error: %v", tc.input, err)
|
||||||
|
}
|
||||||
|
if uint64(*have) != tc.want {
|
||||||
|
t.Errorf("input %q, have %d want %d", tc.input, *have, tc.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ func (beacon *Beacon) VerifyUncles(chain consensus.ChainReader, block *types.Blo
|
|||||||
// (c) the extradata is limited to 32 bytes
|
// (c) the extradata is limited to 32 bytes
|
||||||
func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error {
|
func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error {
|
||||||
// Ensure that the header's extra-data section is of a reasonable size
|
// Ensure that the header's extra-data section is of a reasonable size
|
||||||
if len(header.Extra) > 32 {
|
if len(header.Extra) > int(params.MaximumExtraDataSize) {
|
||||||
return fmt.Errorf("extra-data longer than 32 bytes (%d)", len(header.Extra))
|
return fmt.Errorf("extra-data longer than 32 bytes (%d)", len(header.Extra))
|
||||||
}
|
}
|
||||||
// Verify the seal parts. Ensure the nonce and uncle hash are the expected value.
|
// Verify the seal parts. Ensure the nonce and uncle hash are the expected value.
|
||||||
@@ -387,8 +387,39 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
|
|||||||
// Assign the final state root to header.
|
// Assign the final state root to header.
|
||||||
header.Root = state.IntermediateRoot(true)
|
header.Root = state.IntermediateRoot(true)
|
||||||
|
|
||||||
// Assemble and return the final block.
|
// Assemble the final block.
|
||||||
return types.NewBlockWithWithdrawals(header, body.Transactions, body.Uncles, receipts, body.Withdrawals, trie.NewStackTrie(nil)), nil
|
block := types.NewBlock(header, body, receipts, trie.NewStackTrie(nil))
|
||||||
|
|
||||||
|
// Create the block witness and attach to block.
|
||||||
|
// This step needs to happen as late as possible to catch all access events.
|
||||||
|
if chain.Config().IsVerkle(header.Number, header.Time) {
|
||||||
|
keys := state.AccessEvents().Keys()
|
||||||
|
|
||||||
|
// Open the pre-tree to prove the pre-state against
|
||||||
|
parent := chain.GetHeaderByNumber(header.Number.Uint64() - 1)
|
||||||
|
if parent == nil {
|
||||||
|
return nil, fmt.Errorf("nil parent header for block %d", header.Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
preTrie, err := state.Database().OpenTrie(parent.Root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error opening pre-state tree root: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vktPreTrie, okpre := preTrie.(*trie.VerkleTrie)
|
||||||
|
vktPostTrie, okpost := state.GetTrie().(*trie.VerkleTrie)
|
||||||
|
if okpre && okpost {
|
||||||
|
if len(keys) > 0 {
|
||||||
|
verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys, vktPreTrie.FlatdbNodeResolver)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error generating verkle proof for block %d: %w", header.Number, err)
|
||||||
|
}
|
||||||
|
block = block.WithWitness(&types.ExecutionWitness{StateDiff: stateDiff, VerkleProof: verkleProof})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return block, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seal generates a new sealing request for the given input block and pushes
|
// Seal generates a new sealing request for the given input block and pushes
|
||||||
|
|||||||
@@ -597,7 +597,7 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
|
|||||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||||
|
|
||||||
// Assemble and return the final block for sealing.
|
// Assemble and return the final block for sealing.
|
||||||
return types.NewBlock(header, body.Transactions, nil, receipts, trie.NewStackTrie(nil)), nil
|
return types.NewBlock(header, &types.Body{Transactions: body.Transactions}, receipts, trie.NewStackTrie(nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorize injects a private key into the consensus engine to mint new blocks
|
// Authorize injects a private key into the consensus engine to mint new blocks
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// This test case is a repro of an annoying bug that took us forever to catch.
|
// This test case is a repro of an annoying bug that took us forever to catch.
|
||||||
// In Clique PoA networks (Görli, etc), consecutive blocks might have
|
// In Clique PoA networks, consecutive blocks might have the same state root (no
|
||||||
// the same state root (no block subsidy, empty block). If a node crashes, the
|
// block subsidy, empty block). If a node crashes, the chain ends up losing the
|
||||||
// chain ends up losing the recent state and needs to regenerate it from blocks
|
// recent state and needs to regenerate it from blocks already in the database.
|
||||||
// already in the database. The bug was that processing the block *prior* to an
|
// The bug was that processing the block *prior* to an empty one **also
|
||||||
// empty one **also completes** the empty one, ending up in a known-block error.
|
// completes** the empty one, ending up in a known-block error.
|
||||||
func TestReimportMirroredState(t *testing.T) {
|
func TestReimportMirroredState(t *testing.T) {
|
||||||
// Initialize a Clique chain with a single signer
|
// Initialize a Clique chain with a single signer
|
||||||
var (
|
var (
|
||||||
@@ -55,7 +55,7 @@ func TestReimportMirroredState(t *testing.T) {
|
|||||||
copy(genspec.ExtraData[extraVanity:], addr[:])
|
copy(genspec.ExtraData[extraVanity:], addr[:])
|
||||||
|
|
||||||
// Generate a batch of blocks, each properly signed
|
// Generate a batch of blocks, each properly signed
|
||||||
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genspec, nil, engine, vm.Config{}, nil, nil)
|
chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genspec, nil, engine, vm.Config{}, nil)
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
_, blocks, _ := core.GenerateChainWithGenesis(genspec, engine, 3, func(i int, block *core.BlockGen) {
|
_, blocks, _ := core.GenerateChainWithGenesis(genspec, engine, 3, func(i int, block *core.BlockGen) {
|
||||||
@@ -87,7 +87,7 @@ func TestReimportMirroredState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// Insert the first two blocks and make sure the chain is valid
|
// Insert the first two blocks and make sure the chain is valid
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil, nil)
|
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil)
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if _, err := chain.InsertChain(blocks[:2]); err != nil {
|
if _, err := chain.InsertChain(blocks[:2]); err != nil {
|
||||||
@@ -100,7 +100,7 @@ func TestReimportMirroredState(t *testing.T) {
|
|||||||
// Simulate a crash by creating a new chain on top of the database, without
|
// Simulate a crash by creating a new chain on top of the database, without
|
||||||
// flushing the dirty states out. Insert the last block, triggering a sidechain
|
// flushing the dirty states out. Insert the last block, triggering a sidechain
|
||||||
// reimport.
|
// reimport.
|
||||||
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil, nil)
|
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil)
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
if _, err := chain.InsertChain(blocks[2:]); err != nil {
|
if _, err := chain.InsertChain(blocks[2:]); err != nil {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package clique
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"maps"
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -108,28 +109,16 @@ func (s *Snapshot) store(db ethdb.Database) error {
|
|||||||
|
|
||||||
// copy creates a deep copy of the snapshot, though not the individual votes.
|
// copy creates a deep copy of the snapshot, though not the individual votes.
|
||||||
func (s *Snapshot) copy() *Snapshot {
|
func (s *Snapshot) copy() *Snapshot {
|
||||||
cpy := &Snapshot{
|
return &Snapshot{
|
||||||
config: s.config,
|
config: s.config,
|
||||||
sigcache: s.sigcache,
|
sigcache: s.sigcache,
|
||||||
Number: s.Number,
|
Number: s.Number,
|
||||||
Hash: s.Hash,
|
Hash: s.Hash,
|
||||||
Signers: make(map[common.Address]struct{}),
|
Signers: maps.Clone(s.Signers),
|
||||||
Recents: make(map[uint64]common.Address),
|
Recents: maps.Clone(s.Recents),
|
||||||
Votes: make([]*Vote, len(s.Votes)),
|
Votes: slices.Clone(s.Votes),
|
||||||
Tally: make(map[common.Address]Tally),
|
Tally: maps.Clone(s.Tally),
|
||||||
}
|
}
|
||||||
for signer := range s.Signers {
|
|
||||||
cpy.Signers[signer] = struct{}{}
|
|
||||||
}
|
|
||||||
for block, signer := range s.Recents {
|
|
||||||
cpy.Recents[block] = signer
|
|
||||||
}
|
|
||||||
for address, tally := range s.Tally {
|
|
||||||
cpy.Tally[address] = tally
|
|
||||||
}
|
|
||||||
copy(cpy.Votes, s.Votes)
|
|
||||||
|
|
||||||
return cpy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validVote returns whether it makes sense to cast the specified vote in the
|
// validVote returns whether it makes sense to cast the specified vote in the
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ func (tt *cliqueTest) run(t *testing.T) {
|
|||||||
batches[len(batches)-1] = append(batches[len(batches)-1], block)
|
batches[len(batches)-1] = append(batches[len(batches)-1], block)
|
||||||
}
|
}
|
||||||
// Pass all the headers through clique and ensure tallying succeeds
|
// Pass all the headers through clique and ensure tallying succeeds
|
||||||
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil)
|
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create test chain: %v", err)
|
t.Fatalf("failed to create test chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
|
|||||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||||
|
|
||||||
// Header seems complete, assemble into a block and return
|
// Header seems complete, assemble into a block and return
|
||||||
return types.NewBlock(header, body.Transactions, body.Uncles, receipts, trie.NewStackTrie(nil)), nil
|
return types.NewBlock(header, &types.Body{Transactions: body.Transactions, Uncles: body.Uncles}, receipts, trie.NewStackTrie(nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SealHash returns the hash of a block prior to it being sealed.
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
@@ -562,12 +562,6 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
|
|||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some weird constants to avoid constant memory allocs for them.
|
|
||||||
var (
|
|
||||||
u256_8 = uint256.NewInt(8)
|
|
||||||
u256_32 = uint256.NewInt(32)
|
|
||||||
)
|
|
||||||
|
|
||||||
// accumulateRewards credits the coinbase of the given block with the mining
|
// accumulateRewards credits the coinbase of the given block with the mining
|
||||||
// reward. The total reward consists of the static block reward and rewards for
|
// reward. The total reward consists of the static block reward and rewards for
|
||||||
// included uncles. The coinbase of each uncle block is also rewarded.
|
// included uncles. The coinbase of each uncle block is also rewarded.
|
||||||
@@ -589,10 +583,10 @@ func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, heade
|
|||||||
r.AddUint64(uNum, 8)
|
r.AddUint64(uNum, 8)
|
||||||
r.Sub(r, hNum)
|
r.Sub(r, hNum)
|
||||||
r.Mul(r, blockReward)
|
r.Mul(r, blockReward)
|
||||||
r.Div(r, u256_8)
|
r.Rsh(r, 3)
|
||||||
stateDB.AddBalance(uncle.Coinbase, r, tracing.BalanceIncreaseRewardMineUncle)
|
stateDB.AddBalance(uncle.Coinbase, r, tracing.BalanceIncreaseRewardMineUncle)
|
||||||
|
|
||||||
r.Div(blockReward, u256_32)
|
r.Rsh(blockReward, 5)
|
||||||
reward.Add(reward, r)
|
reward.Add(reward, r)
|
||||||
}
|
}
|
||||||
stateDB.AddBalance(header.Coinbase, reward, tracing.BalanceIncreaseRewardMineBlock)
|
stateDB.AddBalance(header.Coinbase, reward, tracing.BalanceIncreaseRewardMineBlock)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user