Compare commits

..

No commits in common. "master" and "v1.16.2" have entirely different histories.

712 changed files with 27058 additions and 68171 deletions

View file

@ -122,27 +122,6 @@ jobs:
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }}
keeper:
name: Keeper Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.24
cache: false
- name: Install cross toolchain
run: |
apt-get update
apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
- name: Build (amd64)
run: |
go run build/ci.go keeper -dlgo
windows: windows:
name: Windows Build name: Windows Build
runs-on: "win-11" runs-on: "win-11"

2
.github/CODEOWNERS vendored
View file

@ -19,7 +19,7 @@ eth/tracers/ @s1na
ethclient/ @fjl ethclient/ @fjl
ethdb/ @rjl493456442 ethdb/ @rjl493456442
event/ @fjl event/ @fjl
trie/ @rjl493456442 @gballet trie/ @rjl493456442
triedb/ @rjl493456442 triedb/ @rjl493456442
core/tracing/ @s1na core/tracing/ @s1na
graphql/ @s1na graphql/ @s1na

View file

@ -10,7 +10,7 @@ on:
jobs: jobs:
lint: lint:
name: Lint name: Lint
runs-on: [self-hosted-ghr, size-s-x64] runs-on: self-hosted-ghr
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@ -25,7 +25,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: 1.25 go-version: 1.24
cache: false cache: false
- name: Run linters - name: Run linters
@ -34,56 +34,15 @@ jobs:
go run build/ci.go check_generate go run build/ci.go check_generate
go run build/ci.go check_baddeps go run build/ci.go check_baddeps
keeper:
name: Keeper Builds
needs: test
runs-on: [self-hosted-ghr, size-l-x64]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: false
- name: Build
run: go run build/ci.go keeper
test-32bit:
name: "32bit tests"
needs: test
runs-on: [self-hosted-ghr, size-l-x64]
steps:
- uses: actions/checkout@v4
with:
submodules: false
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: false
- name: Install cross toolchain
run: |
sudo apt-get update
sudo apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib
- name: Build
run: go run build/ci.go test -arch 386 -short -p 8
test: test:
name: Test name: Test
needs: lint needs: lint
runs-on: [self-hosted-ghr, size-l-x64] runs-on: self-hosted-ghr
strategy: strategy:
matrix: matrix:
go: go:
- '1.25'
- '1.24' - '1.24'
- '1.23'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@ -96,4 +55,4 @@ jobs:
cache: false cache: false
- name: Run tests - name: Run tests
run: go run build/ci.go test -p 8 run: go test ./...

View file

@ -1,83 +0,0 @@
name: PR Format Validation
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
validate-pr:
runs-on: ubuntu-latest
steps:
- name: Check for Spam PR
uses: actions/github-script@v7
with:
script: |
const prTitle = context.payload.pull_request.title;
const spamRegex = /^(feat|chore|fix)(\(.*\))?\s*:/i;
if (spamRegex.test(prTitle)) {
// Leave a comment explaining why
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `## PR Closed as Spam
This PR was automatically closed because the title format \`feat:\`, \`fix:\`, or \`chore:\` is commonly associated with spam contributions.
If this is a legitimate contribution, please:
1. Review our contribution guidelines
2. Use the correct PR title format: \`directory, ...: description\`
3. Open a new PR with the proper title format
Thank you for your understanding.`
});
// Close the PR
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
state: 'closed'
});
core.setFailed('PR closed as spam due to suspicious title format');
return;
}
console.log('✅ PR passed spam check');
- name: Checkout repository
uses: actions/checkout@v4
- name: Check PR Title Format
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const prTitle = context.payload.pull_request.title;
const titleRegex = /^([\w\s,{}/.]+): .+/;
if (!titleRegex.test(prTitle)) {
core.setFailed(`PR title "${prTitle}" does not match required format: directory, ...: description`);
return;
}
const match = prTitle.match(titleRegex);
const dirPart = match[1];
const directories = dirPart.split(',').map(d => d.trim());
const missingDirs = [];
for (const dir of directories) {
const fullPath = path.join(process.env.GITHUB_WORKSPACE, dir);
if (!fs.existsSync(fullPath)) {
missingDirs.push(dir);
}
}
if (missingDirs.length > 0) {
core.setFailed(`The following directories in the PR title do not exist: ${missingDirs.join(', ')}`);
return;
}
console.log('✅ PR title format is valid');

1
.gitignore vendored
View file

@ -56,4 +56,3 @@ cmd/evm/evm
cmd/geth/geth cmd/geth/geth
cmd/rlpdump/rlpdump cmd/rlpdump/rlpdump
cmd/workload/workload cmd/workload/workload
cmd/keeper/keeper

View file

@ -1,98 +0,0 @@
# AGENTS
## Guidelines
- **Keep changes minimal and focused.** Only modify code directly related to the task at hand. Do not refactor unrelated code, rename existing variables or functions for style, or bundle unrelated fixes into the same commit or PR.
- **Do not add, remove, or update dependencies** unless the task explicitly requires it.
## Pre-Commit Checklist
Before every commit, run **all** of the following checks and ensure they pass:
### 1. Formatting
Before committing, always run `gofmt` and `goimports` on all modified files:
```sh
gofmt -w <modified files>
goimports -w <modified files>
```
### 2. Build All Commands
Verify that all tools compile successfully:
```sh
make all
```
This builds all executables under `cmd/`, including `keeper` which has special build requirements.
### 3. Tests
While iterating during development, use `-short` for faster feedback:
```sh
go run ./build/ci.go test -short
```
Before committing, run the full test suite **without** `-short` to ensure all tests pass, including the Ethereum execution-spec tests and all state/block test permutations:
```sh
go run ./build/ci.go test
```
### 4. Linting
```sh
go run ./build/ci.go lint
```
This runs additional style checks. Fix any issues before committing.
### 5. Generated Code
```sh
go run ./build/ci.go check_generate
```
Ensures that all generated files (e.g., `gen_*.go`) are up to date. If this fails, first install the required code generators by running `make devtools`, then run the appropriate `go generate` commands and include the updated files in your commit.
### 6. Dependency Hygiene
```sh
go run ./build/ci.go check_baddeps
```
Verifies that no forbidden dependencies have been introduced.
## Commit Message Format
Commit messages must be prefixed with the package(s) they modify, followed by a short lowercase description:
```
<package(s)>: description
```
Examples:
- `core/vm: fix stack overflow in PUSH instruction`
- `eth, rpc: make trace configs optional`
- `cmd/geth: add new flag for sync mode`
Use comma-separated package names when multiple areas are affected. Keep the description concise.
## Pull Request Title Format
PR titles follow the same convention as commit messages:
```
<list of modified paths>: description
```
Examples:
- `core/vm: fix stack overflow in PUSH instruction`
- `core, eth: add arena allocator support`
- `cmd/geth, internal/ethapi: refactor transaction args`
- `trie/archiver: streaming subtree archival to fix OOM`
Use the top-level package paths, comma-separated if multiple areas are affected. Only mention the directories with functional changes, interface changes that trickle all over the codebase should not generate an exhaustive list. The description should be a short, lowercase summary of the change.

View file

@ -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.26-alpine AS builder FROM golang:1.24-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

View file

@ -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.26-alpine AS builder FROM golang:1.24-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

View file

@ -8,7 +8,6 @@ https://pkg.go.dev/badge/github.com/ethereum/go-ethereum
[![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) [![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum)
[![Travis](https://app.travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://app.travis-ci.com/github/ethereum/go-ethereum) [![Travis](https://app.travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://app.travis-ci.com/github/ethereum/go-ethereum)
[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv)
[![Twitter](https://img.shields.io/twitter/follow/go_ethereum)](https://x.com/go_ethereum)
Automated builds are available for stable releases and the unstable master branch. Binary Automated builds are available for stable releases and the unstable master branch. Binary
archives are published at https://geth.ethereum.org/downloads/. archives are published at https://geth.ethereum.org/downloads/.

View file

@ -21,6 +21,7 @@ Audit reports are published in the `docs` folder: https://github.com/ethereum/go
To find out how to disclose a vulnerability in Ethereum visit [https://bounty.ethereum.org](https://bounty.ethereum.org) or email bounty@ethereum.org. Please read the [disclosure page](https://github.com/ethereum/go-ethereum/security/advisories?state=published) for more information about publicly disclosed security vulnerabilities. To find out how to disclose a vulnerability in Ethereum visit [https://bounty.ethereum.org](https://bounty.ethereum.org) or email bounty@ethereum.org. Please read the [disclosure page](https://github.com/ethereum/go-ethereum/security/advisories?state=published) for more information about publicly disclosed security vulnerabilities.
Use the built-in `geth version-check` feature to check whether the software is affected by any known vulnerability. This command will fetch the latest [`vulnerabilities.json`](https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json) file which contains known security vulnerabilities concerning `geth`, and cross-check the data against its own version number.
The following key may be used to communicate sensitive information to developers. The following key may be used to communicate sensitive information to developers.

View file

@ -485,13 +485,13 @@ var bindTests = []struct {
contract Defaulter { contract Defaulter {
address public caller; address public caller;
fallback() external payable { function() {
caller = msg.sender; caller = msg.sender;
} }
} }
`, `,
[]string{`608060405234801561000f575f80fd5b5061013d8061001d5f395ff3fe608060405260043610610021575f3560e01c8063fc9c8d391461006257610022565b5b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055005b34801561006d575f80fd5b5061007661008c565b60405161008391906100ee565b60405180910390f35b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100d8826100af565b9050919050565b6100e8816100ce565b82525050565b5f6020820190506101015f8301846100df565b9291505056fea26469706673582212201e9273ecfb1f534644c77f09a25c21baaba81cf1c444ebc071e12a225a23c72964736f6c63430008140033`}, []string{`6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`},
[]string{`[{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"caller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]`}, []string{`[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`},
` `
"math/big" "math/big"

View file

@ -183,7 +183,7 @@ var (
// Solidity: {{.Original.String}} // Solidity: {{.Original.String}}
func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}Event(log *types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}Event(log *types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
event := "{{.Original.Name}}" event := "{{.Original.Name}}"
if len(log.Topics) == 0 || log.Topics[0] != {{ decapitalise $contract.Type}}.abi.Events[event].ID { if log.Topics[0] != {{ decapitalise $contract.Type}}.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new({{$contract.Type}}{{.Normalized.Name}}) out := new({{$contract.Type}}{{.Normalized.Name}})

View file

@ -360,7 +360,7 @@ func (CrowdsaleFundTransfer) ContractEventName() string {
// Solidity: event FundTransfer(address backer, uint256 amount, bool isContribution) // Solidity: event FundTransfer(address backer, uint256 amount, bool isContribution)
func (crowdsale *Crowdsale) UnpackFundTransferEvent(log *types.Log) (*CrowdsaleFundTransfer, error) { func (crowdsale *Crowdsale) UnpackFundTransferEvent(log *types.Log) (*CrowdsaleFundTransfer, error) {
event := "FundTransfer" event := "FundTransfer"
if len(log.Topics) == 0 || log.Topics[0] != crowdsale.abi.Events[event].ID { if log.Topics[0] != crowdsale.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(CrowdsaleFundTransfer) out := new(CrowdsaleFundTransfer)

View file

@ -606,7 +606,7 @@ func (DAOChangeOfRules) ContractEventName() string {
// Solidity: event ChangeOfRules(uint256 minimumQuorum, uint256 debatingPeriodInMinutes, int256 majorityMargin) // Solidity: event ChangeOfRules(uint256 minimumQuorum, uint256 debatingPeriodInMinutes, int256 majorityMargin)
func (dAO *DAO) UnpackChangeOfRulesEvent(log *types.Log) (*DAOChangeOfRules, error) { func (dAO *DAO) UnpackChangeOfRulesEvent(log *types.Log) (*DAOChangeOfRules, error) {
event := "ChangeOfRules" event := "ChangeOfRules"
if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { if log.Topics[0] != dAO.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DAOChangeOfRules) out := new(DAOChangeOfRules)
@ -648,7 +648,7 @@ func (DAOMembershipChanged) ContractEventName() string {
// Solidity: event MembershipChanged(address member, bool isMember) // Solidity: event MembershipChanged(address member, bool isMember)
func (dAO *DAO) UnpackMembershipChangedEvent(log *types.Log) (*DAOMembershipChanged, error) { func (dAO *DAO) UnpackMembershipChangedEvent(log *types.Log) (*DAOMembershipChanged, error) {
event := "MembershipChanged" event := "MembershipChanged"
if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { if log.Topics[0] != dAO.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DAOMembershipChanged) out := new(DAOMembershipChanged)
@ -692,7 +692,7 @@ func (DAOProposalAdded) ContractEventName() string {
// Solidity: event ProposalAdded(uint256 proposalID, address recipient, uint256 amount, string description) // Solidity: event ProposalAdded(uint256 proposalID, address recipient, uint256 amount, string description)
func (dAO *DAO) UnpackProposalAddedEvent(log *types.Log) (*DAOProposalAdded, error) { func (dAO *DAO) UnpackProposalAddedEvent(log *types.Log) (*DAOProposalAdded, error) {
event := "ProposalAdded" event := "ProposalAdded"
if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { if log.Topics[0] != dAO.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DAOProposalAdded) out := new(DAOProposalAdded)
@ -736,7 +736,7 @@ func (DAOProposalTallied) ContractEventName() string {
// Solidity: event ProposalTallied(uint256 proposalID, int256 result, uint256 quorum, bool active) // Solidity: event ProposalTallied(uint256 proposalID, int256 result, uint256 quorum, bool active)
func (dAO *DAO) UnpackProposalTalliedEvent(log *types.Log) (*DAOProposalTallied, error) { func (dAO *DAO) UnpackProposalTalliedEvent(log *types.Log) (*DAOProposalTallied, error) {
event := "ProposalTallied" event := "ProposalTallied"
if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { if log.Topics[0] != dAO.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DAOProposalTallied) out := new(DAOProposalTallied)
@ -780,7 +780,7 @@ func (DAOVoted) ContractEventName() string {
// Solidity: event Voted(uint256 proposalID, bool position, address voter, string justification) // Solidity: event Voted(uint256 proposalID, bool position, address voter, string justification)
func (dAO *DAO) UnpackVotedEvent(log *types.Log) (*DAOVoted, error) { func (dAO *DAO) UnpackVotedEvent(log *types.Log) (*DAOVoted, error) {
event := "Voted" event := "Voted"
if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { if log.Topics[0] != dAO.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DAOVoted) out := new(DAOVoted)

View file

@ -72,7 +72,7 @@ func (EventCheckerDynamic) ContractEventName() string {
// Solidity: event dynamic(string indexed idxStr, bytes indexed idxDat, string str, bytes dat) // Solidity: event dynamic(string indexed idxStr, bytes indexed idxDat, string str, bytes dat)
func (eventChecker *EventChecker) UnpackDynamicEvent(log *types.Log) (*EventCheckerDynamic, error) { func (eventChecker *EventChecker) UnpackDynamicEvent(log *types.Log) (*EventCheckerDynamic, error) {
event := "dynamic" event := "dynamic"
if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { if log.Topics[0] != eventChecker.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(EventCheckerDynamic) out := new(EventCheckerDynamic)
@ -112,7 +112,7 @@ func (EventCheckerEmpty) ContractEventName() string {
// Solidity: event empty() // Solidity: event empty()
func (eventChecker *EventChecker) UnpackEmptyEvent(log *types.Log) (*EventCheckerEmpty, error) { func (eventChecker *EventChecker) UnpackEmptyEvent(log *types.Log) (*EventCheckerEmpty, error) {
event := "empty" event := "empty"
if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { if log.Topics[0] != eventChecker.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(EventCheckerEmpty) out := new(EventCheckerEmpty)
@ -154,7 +154,7 @@ func (EventCheckerIndexed) ContractEventName() string {
// Solidity: event indexed(address indexed addr, int256 indexed num) // Solidity: event indexed(address indexed addr, int256 indexed num)
func (eventChecker *EventChecker) UnpackIndexedEvent(log *types.Log) (*EventCheckerIndexed, error) { func (eventChecker *EventChecker) UnpackIndexedEvent(log *types.Log) (*EventCheckerIndexed, error) {
event := "indexed" event := "indexed"
if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { if log.Topics[0] != eventChecker.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(EventCheckerIndexed) out := new(EventCheckerIndexed)
@ -196,7 +196,7 @@ func (EventCheckerMixed) ContractEventName() string {
// Solidity: event mixed(address indexed addr, int256 num) // Solidity: event mixed(address indexed addr, int256 num)
func (eventChecker *EventChecker) UnpackMixedEvent(log *types.Log) (*EventCheckerMixed, error) { func (eventChecker *EventChecker) UnpackMixedEvent(log *types.Log) (*EventCheckerMixed, error) {
event := "mixed" event := "mixed"
if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { if log.Topics[0] != eventChecker.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(EventCheckerMixed) out := new(EventCheckerMixed)
@ -238,7 +238,7 @@ func (EventCheckerUnnamed) ContractEventName() string {
// Solidity: event unnamed(uint256 indexed arg0, uint256 indexed arg1) // Solidity: event unnamed(uint256 indexed arg0, uint256 indexed arg1)
func (eventChecker *EventChecker) UnpackUnnamedEvent(log *types.Log) (*EventCheckerUnnamed, error) { func (eventChecker *EventChecker) UnpackUnnamedEvent(log *types.Log) (*EventCheckerUnnamed, error) {
event := "unnamed" event := "unnamed"
if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { if log.Topics[0] != eventChecker.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(EventCheckerUnnamed) out := new(EventCheckerUnnamed)

View file

@ -134,7 +134,7 @@ func (NameConflictLog) ContractEventName() string {
// Solidity: event log(int256 msg, int256 _msg) // Solidity: event log(int256 msg, int256 _msg)
func (nameConflict *NameConflict) UnpackLogEvent(log *types.Log) (*NameConflictLog, error) { func (nameConflict *NameConflict) UnpackLogEvent(log *types.Log) (*NameConflictLog, error) {
event := "log" event := "log"
if len(log.Topics) == 0 || log.Topics[0] != nameConflict.abi.Events[event].ID { if log.Topics[0] != nameConflict.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(NameConflictLog) out := new(NameConflictLog)

View file

@ -136,7 +136,7 @@ func (NumericMethodNameE1TestEvent) ContractEventName() string {
// Solidity: event _1TestEvent(address _param) // Solidity: event _1TestEvent(address _param)
func (numericMethodName *NumericMethodName) UnpackE1TestEventEvent(log *types.Log) (*NumericMethodNameE1TestEvent, error) { func (numericMethodName *NumericMethodName) UnpackE1TestEventEvent(log *types.Log) (*NumericMethodNameE1TestEvent, error) {
event := "_1TestEvent" event := "_1TestEvent"
if len(log.Topics) == 0 || log.Topics[0] != numericMethodName.abi.Events[event].ID { if log.Topics[0] != numericMethodName.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(NumericMethodNameE1TestEvent) out := new(NumericMethodNameE1TestEvent)

View file

@ -114,7 +114,7 @@ func (OverloadBar) ContractEventName() string {
// Solidity: event bar(uint256 i) // Solidity: event bar(uint256 i)
func (overload *Overload) UnpackBarEvent(log *types.Log) (*OverloadBar, error) { func (overload *Overload) UnpackBarEvent(log *types.Log) (*OverloadBar, error) {
event := "bar" event := "bar"
if len(log.Topics) == 0 || log.Topics[0] != overload.abi.Events[event].ID { if log.Topics[0] != overload.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(OverloadBar) out := new(OverloadBar)
@ -156,7 +156,7 @@ func (OverloadBar0) ContractEventName() string {
// Solidity: event bar(uint256 i, uint256 j) // Solidity: event bar(uint256 i, uint256 j)
func (overload *Overload) UnpackBar0Event(log *types.Log) (*OverloadBar0, error) { func (overload *Overload) UnpackBar0Event(log *types.Log) (*OverloadBar0, error) {
event := "bar0" event := "bar0"
if len(log.Topics) == 0 || log.Topics[0] != overload.abi.Events[event].ID { if log.Topics[0] != overload.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(OverloadBar0) out := new(OverloadBar0)

View file

@ -386,7 +386,7 @@ func (TokenTransfer) ContractEventName() string {
// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) // Solidity: event Transfer(address indexed from, address indexed to, uint256 value)
func (token *Token) UnpackTransferEvent(log *types.Log) (*TokenTransfer, error) { func (token *Token) UnpackTransferEvent(log *types.Log) (*TokenTransfer, error) {
event := "Transfer" event := "Transfer"
if len(log.Topics) == 0 || log.Topics[0] != token.abi.Events[event].ID { if log.Topics[0] != token.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(TokenTransfer) out := new(TokenTransfer)

View file

@ -193,7 +193,7 @@ func (TupleTupleEvent) ContractEventName() string {
// Solidity: event TupleEvent((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) // Solidity: event TupleEvent((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e)
func (tuple *Tuple) UnpackTupleEventEvent(log *types.Log) (*TupleTupleEvent, error) { func (tuple *Tuple) UnpackTupleEventEvent(log *types.Log) (*TupleTupleEvent, error) {
event := "TupleEvent" event := "TupleEvent"
if len(log.Topics) == 0 || log.Topics[0] != tuple.abi.Events[event].ID { if log.Topics[0] != tuple.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(TupleTupleEvent) out := new(TupleTupleEvent)
@ -234,7 +234,7 @@ func (TupleTupleEvent2) ContractEventName() string {
// Solidity: event TupleEvent2((uint8,uint8)[] arg0) // Solidity: event TupleEvent2((uint8,uint8)[] arg0)
func (tuple *Tuple) UnpackTupleEvent2Event(log *types.Log) (*TupleTupleEvent2, error) { func (tuple *Tuple) UnpackTupleEvent2Event(log *types.Log) (*TupleTupleEvent2, error) {
event := "TupleEvent2" event := "TupleEvent2"
if len(log.Topics) == 0 || log.Topics[0] != tuple.abi.Events[event].ID { if log.Topics[0] != tuple.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(TupleTupleEvent2) out := new(TupleTupleEvent2)

View file

@ -150,11 +150,6 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller
} }
} }
// Address returns the deployment address of the contract.
func (c *BoundContract) Address() common.Address {
return c.address
}
// Call invokes the (constant) contract method with params as input values and // 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 // 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, a slice of interfaces for anonymous returns and a struct for named
@ -277,10 +272,8 @@ func (c *BoundContract) RawCreationTransact(opts *TransactOpts, calldata []byte)
// Transfer initiates a plain transaction to move funds to the contract, calling // Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available. // its default method if one is available.
func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) { func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) {
// Check if payable fallback or receive is defined // todo(rjl493456442) check the payable fallback or receive is defined
if !c.abi.HasReceive() && !(c.abi.HasFallback() && c.abi.Fallback.IsPayable()) { // or not, reject invalid transaction at the first place
return nil, fmt.Errorf("contract does not have a payable fallback or receive function")
}
return c.transact(opts, &c.address, nil) return c.transact(opts, &c.address, nil)
} }

View file

@ -158,10 +158,10 @@ func testLinkCase(tcInput linkTestCaseInput) error {
overrideAddrs = make(map[rune]common.Address) overrideAddrs = make(map[rune]common.Address)
) )
// generate deterministic addresses for the override set. // generate deterministic addresses for the override set.
rng := rand.New(rand.NewSource(42)) rand.Seed(42)
for contract := range tcInput.overrides { for contract := range tcInput.overrides {
var addr common.Address var addr common.Address
rng.Read(addr[:]) rand.Read(addr[:])
overrideAddrs[contract] = addr overrideAddrs[contract] = addr
overridesAddrs[addr] = struct{}{} overridesAddrs[addr] = struct{}{}
} }

View file

@ -276,7 +276,7 @@ func (DBInsert) ContractEventName() string {
// Solidity: event Insert(uint256 key, uint256 value, uint256 length) // Solidity: event Insert(uint256 key, uint256 value, uint256 length)
func (dB *DB) UnpackInsertEvent(log *types.Log) (*DBInsert, error) { func (dB *DB) UnpackInsertEvent(log *types.Log) (*DBInsert, error) {
event := "Insert" event := "Insert"
if len(log.Topics) == 0 || log.Topics[0] != dB.abi.Events[event].ID { if log.Topics[0] != dB.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DBInsert) out := new(DBInsert)
@ -318,7 +318,7 @@ func (DBKeyedInsert) ContractEventName() string {
// Solidity: event KeyedInsert(uint256 indexed key, uint256 value) // Solidity: event KeyedInsert(uint256 indexed key, uint256 value)
func (dB *DB) UnpackKeyedInsertEvent(log *types.Log) (*DBKeyedInsert, error) { func (dB *DB) UnpackKeyedInsertEvent(log *types.Log) (*DBKeyedInsert, error) {
event := "KeyedInsert" event := "KeyedInsert"
if len(log.Topics) == 0 || log.Topics[0] != dB.abi.Events[event].ID { if log.Topics[0] != dB.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(DBKeyedInsert) out := new(DBKeyedInsert)

View file

@ -115,7 +115,7 @@ func (CBasic1) ContractEventName() string {
// Solidity: event basic1(uint256 indexed id, uint256 data) // Solidity: event basic1(uint256 indexed id, uint256 data)
func (c *C) UnpackBasic1Event(log *types.Log) (*CBasic1, error) { func (c *C) UnpackBasic1Event(log *types.Log) (*CBasic1, error) {
event := "basic1" event := "basic1"
if len(log.Topics) == 0 || log.Topics[0] != c.abi.Events[event].ID { if log.Topics[0] != c.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(CBasic1) out := new(CBasic1)
@ -157,7 +157,7 @@ func (CBasic2) ContractEventName() string {
// Solidity: event basic2(bool indexed flag, uint256 data) // Solidity: event basic2(bool indexed flag, uint256 data)
func (c *C) UnpackBasic2Event(log *types.Log) (*CBasic2, error) { func (c *C) UnpackBasic2Event(log *types.Log) (*CBasic2, error) {
event := "basic2" event := "basic2"
if len(log.Topics) == 0 || log.Topics[0] != c.abi.Events[event].ID { if log.Topics[0] != c.abi.Events[event].ID {
return nil, errors.New("event signature mismatch") return nil, errors.New("event signature mismatch")
} }
out := new(CBasic2) out := new(CBasic2)

View file

@ -367,28 +367,3 @@ func TestErrors(t *testing.T) {
t.Fatalf("bad unpacked error result: expected Arg4 to be false. got true") t.Fatalf("bad unpacked error result: expected Arg4 to be false. got true")
} }
} }
func TestEventUnpackEmptyTopics(t *testing.T) {
c := events.NewC()
for _, log := range []*types.Log{
{Topics: []common.Hash{}},
{Topics: nil},
} {
_, err := c.UnpackBasic1Event(log)
if err == nil {
t.Fatal("expected error when unpacking event with empty topics, got nil")
}
if err.Error() != "event signature mismatch" {
t.Fatalf("expected 'event signature mismatch' error, got: %v", err)
}
_, err = c.UnpackBasic2Event(log)
if err == nil {
t.Fatal("expected error when unpacking event with empty topics, got nil")
}
if err.Error() != "event signature mismatch" {
t.Fatalf("expected 'event signature mismatch' error, got: %v", err)
}
}
}

View file

@ -100,29 +100,22 @@ func TestWaitDeployed(t *testing.T) {
} }
func TestWaitDeployedCornerCases(t *testing.T) { func TestWaitDeployedCornerCases(t *testing.T) {
var ( backend := simulated.NewBackend(
backend = simulated.NewBackend( types.GenesisAlloc{
types.GenesisAlloc{ crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)},
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)}, },
},
)
head, _ = backend.Client().HeaderByNumber(t.Context(), nil) // Should be child's, good enough
gasPrice = new(big.Int).Add(head.BaseFee, big.NewInt(1))
signer = types.LatestSigner(params.AllDevChainProtocolChanges)
code = common.FromHex("6060604052600a8060106000396000f360606040526008565b00")
ctx, cancel = context.WithCancel(t.Context())
) )
defer backend.Close() defer backend.Close()
// 1. WaitDeploy on a transaction that does not deploy a contract, verify it head, _ := backend.Client().HeaderByNumber(context.Background(), nil) // Should be child's, good enough
// returns an error. gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1))
tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{
Nonce: 0, // Create a transaction to an account.
To: &common.Address{0x01}, code := "6060604052600a8060106000396000f360606040526008565b00"
Gas: 300000, tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
GasPrice: gasPrice, tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
Data: code, ctx, cancel := context.WithCancel(context.Background())
}) defer cancel()
if err := backend.Client().SendTransaction(ctx, tx); err != nil { if err := backend.Client().SendTransaction(ctx, tx); err != nil {
t.Errorf("failed to send transaction: %q", err) t.Errorf("failed to send transaction: %q", err)
} }
@ -131,22 +124,14 @@ func TestWaitDeployedCornerCases(t *testing.T) {
t.Errorf("error mismatch: want %q, got %q, ", bind.ErrNoAddressInReceipt, err) t.Errorf("error mismatch: want %q, got %q, ", bind.ErrNoAddressInReceipt, err)
} }
// 2. Create a contract, but cancel the WaitDeploy before it is mined. // Create a transaction that is not mined.
tx = types.MustSignNewTx(testKey, signer, &types.LegacyTx{ tx = types.NewContractCreation(1, big.NewInt(0), 3000000, gasPrice, common.FromHex(code))
Nonce: 1, tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey)
Gas: 300000,
GasPrice: gasPrice,
Data: code,
})
// Wait in another thread so that we can quickly cancel it after submitting
// the transaction.
done := make(chan struct{})
go func() { go func() {
defer close(done) contextCanceled := errors.New("context canceled")
_, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()) if _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()); err.Error() != contextCanceled.Error() {
if !errors.Is(err, context.Canceled) { t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err)
t.Errorf("error mismatch: want %v, got %v", context.Canceled, err)
} }
}() }()
@ -154,11 +139,4 @@ func TestWaitDeployedCornerCases(t *testing.T) {
t.Errorf("failed to send transaction: %q", err) t.Errorf("failed to send transaction: %q", err)
} }
cancel() cancel()
// Wait for goroutine to exit or for a timeout.
select {
case <-done:
case <-time.After(time.Second * 2):
t.Fatalf("failed to cancel wait deploy")
}
} }

View file

@ -53,7 +53,7 @@ func ConvertType(in interface{}, proto interface{}) interface{} {
// indirect recursively dereferences the value until it either gets the value // indirect recursively dereferences the value until it either gets the value
// or finds a big.Int // or finds a big.Int
func indirect(v reflect.Value) reflect.Value { func indirect(v reflect.Value) reflect.Value {
if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeFor[big.Int]() { if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeOf(big.Int{}) {
return indirect(v.Elem()) return indirect(v.Elem())
} }
return v return v
@ -65,32 +65,32 @@ func reflectIntType(unsigned bool, size int) reflect.Type {
if unsigned { if unsigned {
switch size { switch size {
case 8: case 8:
return reflect.TypeFor[uint8]() return reflect.TypeOf(uint8(0))
case 16: case 16:
return reflect.TypeFor[uint16]() return reflect.TypeOf(uint16(0))
case 32: case 32:
return reflect.TypeFor[uint32]() return reflect.TypeOf(uint32(0))
case 64: case 64:
return reflect.TypeFor[uint64]() return reflect.TypeOf(uint64(0))
} }
} }
switch size { switch size {
case 8: case 8:
return reflect.TypeFor[int8]() return reflect.TypeOf(int8(0))
case 16: case 16:
return reflect.TypeFor[int16]() return reflect.TypeOf(int16(0))
case 32: case 32:
return reflect.TypeFor[int32]() return reflect.TypeOf(int32(0))
case 64: case 64:
return reflect.TypeFor[int64]() return reflect.TypeOf(int64(0))
} }
return reflect.TypeFor[*big.Int]() return reflect.TypeOf(&big.Int{})
} }
// mustArrayToByteSlice creates a new byte slice with the exact same size as value // mustArrayToByteSlice creates a new byte slice with the exact same size as value
// and copies the bytes in value to the new slice. // and copies the bytes in value to the new slice.
func mustArrayToByteSlice(value reflect.Value) reflect.Value { func mustArrayToByteSlice(value reflect.Value) reflect.Value {
slice := reflect.ValueOf(make([]byte, value.Len())) slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
reflect.Copy(slice, value) reflect.Copy(slice, value)
return slice return slice
} }
@ -104,7 +104,7 @@ func set(dst, src reflect.Value) error {
switch { switch {
case dstType.Kind() == reflect.Interface && dst.Elem().IsValid() && (dst.Elem().Type().Kind() == reflect.Ptr || dst.Elem().CanSet()): case dstType.Kind() == reflect.Interface && dst.Elem().IsValid() && (dst.Elem().Type().Kind() == reflect.Ptr || dst.Elem().CanSet()):
return set(dst.Elem(), src) return set(dst.Elem(), src)
case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeFor[big.Int](): case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeOf(big.Int{}):
return set(dst.Elem(), src) return set(dst.Elem(), src)
case srcType.AssignableTo(dstType) && dst.CanSet(): case srcType.AssignableTo(dstType) && dst.CanSet():
dst.Set(src) dst.Set(src)

View file

@ -204,12 +204,12 @@ func TestConvertType(t *testing.T) {
var fields []reflect.StructField var fields []reflect.StructField
fields = append(fields, reflect.StructField{ fields = append(fields, reflect.StructField{
Name: "X", Name: "X",
Type: reflect.TypeFor[*big.Int](), Type: reflect.TypeOf(new(big.Int)),
Tag: "json:\"" + "x" + "\"", Tag: "json:\"" + "x" + "\"",
}) })
fields = append(fields, reflect.StructField{ fields = append(fields, reflect.StructField{
Name: "Y", Name: "Y",
Type: reflect.TypeFor[*big.Int](), Type: reflect.TypeOf(new(big.Int)),
Tag: "json:\"" + "y" + "\"", Tag: "json:\"" + "y" + "\"",
}) })
val := reflect.New(reflect.StructOf(fields)) val := reflect.New(reflect.StructOf(fields))

View file

@ -238,9 +238,9 @@ func (t Type) GetType() reflect.Type {
case UintTy: case UintTy:
return reflectIntType(true, t.Size) return reflectIntType(true, t.Size)
case BoolTy: case BoolTy:
return reflect.TypeFor[bool]() return reflect.TypeOf(false)
case StringTy: case StringTy:
return reflect.TypeFor[string]() return reflect.TypeOf("")
case SliceTy: case SliceTy:
return reflect.SliceOf(t.Elem.GetType()) return reflect.SliceOf(t.Elem.GetType())
case ArrayTy: case ArrayTy:
@ -248,15 +248,19 @@ func (t Type) GetType() reflect.Type {
case TupleTy: case TupleTy:
return t.TupleType return t.TupleType
case AddressTy: case AddressTy:
return reflect.TypeFor[common.Address]() return reflect.TypeOf(common.Address{})
case FixedBytesTy: case FixedBytesTy:
return reflect.ArrayOf(t.Size, reflect.TypeFor[byte]()) return reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0)))
case BytesTy: case BytesTy:
return reflect.TypeFor[[]byte]() return reflect.SliceOf(reflect.TypeOf(byte(0)))
case HashTy, FixedPointTy: // currently not used case HashTy:
return reflect.TypeFor[[32]byte]() // hashtype currently not used
return reflect.ArrayOf(32, reflect.TypeOf(byte(0)))
case FixedPointTy:
// fixedpoint type currently not used
return reflect.ArrayOf(32, reflect.TypeOf(byte(0)))
case FunctionTy: case FunctionTy:
return reflect.TypeFor[[24]byte]() return reflect.ArrayOf(24, reflect.TypeOf(byte(0)))
default: default:
panic("Invalid type") panic("Invalid type")
} }

View file

@ -24,8 +24,8 @@ import (
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/keccak"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"golang.org/x/crypto/sha3"
) )
// Account represents an Ethereum account located at a specific location defined // Account represents an Ethereum account located at a specific location defined
@ -196,7 +196,7 @@ func TextHash(data []byte) []byte {
// This gives context to the signed message and prevents signing of transactions. // This gives context to the signed message and prevents signing of transactions.
func TextAndHash(data []byte) ([]byte, string) { func TextAndHash(data []byte) ([]byte, string) {
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
hasher := keccak.NewLegacyKeccak256() hasher := sha3.NewLegacyKeccak256()
hasher.Write([]byte(msg)) hasher.Write([]byte(msg))
return hasher.Sum(nil), msg return hasher.Sum(nil), msg
} }

View file

@ -50,7 +50,7 @@ var (
) )
// KeyStoreType is the reflect type of a keystore backend. // KeyStoreType is the reflect type of a keystore backend.
var KeyStoreType = reflect.TypeFor[*KeyStore]() var KeyStoreType = reflect.TypeOf(&KeyStore{})
// KeyStoreScheme is the protocol scheme prefixing account and wallet URLs. // KeyStoreScheme is the protocol scheme prefixing account and wallet URLs.
const KeyStoreScheme = "keystore" const KeyStoreScheme = "keystore"
@ -99,10 +99,9 @@ func (ks *KeyStore) init(keydir string) {
// TODO: In order for this finalizer to work, there must be no references // TODO: In order for this finalizer to work, there must be no references
// to ks. addressCache doesn't keep a reference but unlocked keys do, // to ks. addressCache doesn't keep a reference but unlocked keys do,
// so the finalizer will not trigger until all timed unlocks have expired. // so the finalizer will not trigger until all timed unlocks have expired.
runtime.AddCleanup(ks, func(c *accountCache) { runtime.SetFinalizer(ks, func(m *KeyStore) {
c.close() m.cache.close()
}, ks.cache) })
// Create the initial list of wallets from the cache // Create the initial list of wallets from the cache
accs := ks.cache.accounts() accs := ks.cache.accounts()
ks.wallets = make([]accounts.Wallet, len(accs)) ks.wallets = make([]accounts.Wallet, len(accs))
@ -196,14 +195,11 @@ func (ks *KeyStore) Subscribe(sink chan<- accounts.WalletEvent) event.Subscripti
// forces a manual refresh (only triggers for systems where the filesystem notifier // forces a manual refresh (only triggers for systems where the filesystem notifier
// is not running). // is not running).
func (ks *KeyStore) updater() { func (ks *KeyStore) updater() {
ticker := time.NewTicker(walletRefreshCycle)
defer ticker.Stop()
for { for {
// Wait for an account update or a refresh timeout // Wait for an account update or a refresh timeout
select { select {
case <-ks.changes: case <-ks.changes:
case <-ticker.C: case <-time.After(walletRefreshCycle):
} }
// Run the wallet refresher // Run the wallet refresher
ks.refreshWallets() ks.refreshWallets()
@ -418,7 +414,6 @@ func (ks *KeyStore) Export(a accounts.Account, passphrase, newPassphrase string)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer zeroKey(key.PrivateKey)
var N, P int var N, P int
if store, ok := ks.storage.(*keyStorePassphrase); ok { if store, ok := ks.storage.(*keyStorePassphrase); ok {
N, P = store.scryptN, store.scryptP N, P = store.scryptN, store.scryptP
@ -478,7 +473,6 @@ func (ks *KeyStore) Update(a accounts.Account, passphrase, newPassphrase string)
if err != nil { if err != nil {
return err return err
} }
defer zeroKey(key.PrivateKey)
return ks.storage.StoreKey(a.URL.Path, key, newPassphrase) return ks.storage.StoreKey(a.URL.Path, key, newPassphrase)
} }

View file

@ -81,9 +81,6 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error
*/ */
passBytes := []byte(password) passBytes := []byte(password)
derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New) derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New)
if len(cipherText)%aes.BlockSize != 0 {
return nil, errors.New("ciphertext must be a multiple of block size")
}
plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -300,10 +300,6 @@ func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) {
return nil, err return nil, err
} }
if len(data) == 0 || len(data)%aes.BlockSize != 0 {
return nil, fmt.Errorf("invalid ciphertext length: %d", len(data))
}
ret := make([]byte, len(data)) ret := make([]byte, len(data))
crypter := cipher.NewCBCDecrypter(a, s.iv) crypter := cipher.NewCBCDecrypter(a, s.iv)

View file

@ -472,11 +472,6 @@ func (w *Wallet) selfDerive() {
continue continue
} }
pairing := w.Hub.pairing(w) pairing := w.Hub.pairing(w)
if pairing == nil {
w.lock.Unlock()
reqc <- struct{}{}
continue
}
// Device lock obtained, derive the next batch of accounts // Device lock obtained, derive the next batch of accounts
var ( var (
@ -636,13 +631,13 @@ func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun
} }
if pin { if pin {
if pairing := w.Hub.pairing(w); pairing != nil { pairing := w.Hub.pairing(w)
pairing.Accounts[account.Address] = path pairing.Accounts[account.Address] = path
if err := w.Hub.setPairing(w, pairing); err != nil { if err := w.Hub.setPairing(w, pairing); err != nil {
return accounts.Account{}, err return accounts.Account{}, err
}
} }
} }
return account, nil return account, nil
} }
@ -779,11 +774,11 @@ func (w *Wallet) SignTxWithPassphrase(account accounts.Account, passphrase strin
// It first checks for the address in the list of pinned accounts, and if it is // It first checks for the address in the list of pinned accounts, and if it is
// not found, attempts to parse the derivation path from the account's URL. // not found, attempts to parse the derivation path from the account's URL.
func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) { func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) {
if pairing := w.Hub.pairing(w); pairing != nil { pairing := w.Hub.pairing(w)
if path, ok := pairing.Accounts[account.Address]; ok { if path, ok := pairing.Accounts[account.Address]; ok {
return path, nil return path, nil
}
} }
// Look for the path in the URL // Look for the path in the URL
if account.URL.Scheme != w.Hub.scheme { if account.URL.Scheme != w.Hub.scheme {
return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme)

View file

@ -43,14 +43,6 @@ const refreshCycle = time.Second
// trashing. // trashing.
const refreshThrottling = 500 * time.Millisecond const refreshThrottling = 500 * time.Millisecond
const (
// deviceUsagePage identifies Ledger devices by HID usage page (0xffa0) on Windows and macOS.
// See: https://github.com/LedgerHQ/ledger-live/blob/05a2980e838955a11a1418da638ef8ac3df4fb74/libs/ledgerjs/packages/hw-transport-node-hid-noevents/src/TransportNodeHid.ts
deviceUsagePage = 0xffa0
// deviceInterface identifies Ledger devices by USB interface number (0) on Linux.
deviceInterface = 0
)
// Hub is a accounts.Backend that can find and handle generic USB hardware wallets. // Hub is a accounts.Backend that can find and handle generic USB hardware wallets.
type Hub struct { type Hub struct {
scheme string // Protocol scheme prefixing account and wallet URLs. scheme string // Protocol scheme prefixing account and wallet URLs.
@ -90,7 +82,6 @@ func NewLedgerHub() (*Hub, error) {
0x0005, /* Ledger Nano S Plus */ 0x0005, /* Ledger Nano S Plus */
0x0006, /* Ledger Nano FTS */ 0x0006, /* Ledger Nano FTS */
0x0007, /* Ledger Flex */ 0x0007, /* Ledger Flex */
0x0008, /* Ledger Nano Gen5 */
0x0000, /* WebUSB Ledger Blue */ 0x0000, /* WebUSB Ledger Blue */
0x1000, /* WebUSB Ledger Nano S */ 0x1000, /* WebUSB Ledger Nano S */
@ -98,8 +89,7 @@ func NewLedgerHub() (*Hub, error) {
0x5000, /* WebUSB Ledger Nano S Plus */ 0x5000, /* WebUSB Ledger Nano S Plus */
0x6000, /* WebUSB Ledger Nano FTS */ 0x6000, /* WebUSB Ledger Nano FTS */
0x7000, /* WebUSB Ledger Flex */ 0x7000, /* WebUSB Ledger Flex */
0x8000, /* WebUSB Ledger Nano Gen5 */ }, 0xffa0, 0, newLedgerDriver)
}, deviceUsagePage, deviceInterface, newLedgerDriver)
} }
// NewTrezorHubWithHID creates a new hardware wallet manager for Trezor devices. // NewTrezorHubWithHID creates a new hardware wallet manager for Trezor devices.

View file

@ -166,7 +166,7 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
return common.Address{}, nil, accounts.ErrWalletClosed return common.Address{}, nil, accounts.ErrWalletClosed
} }
// Ensure the wallet is capable of signing the given transaction // Ensure the wallet is capable of signing the given transaction
if chainID != nil && (w.version[0] < 1 || (w.version[0] == 1 && w.version[1] == 0 && w.version[2] < 3)) { if chainID != nil && w.version[0] <= 1 && w.version[1] <= 0 && w.version[2] <= 2 {
//lint:ignore ST1005 brand name displayed on the console //lint:ignore ST1005 brand name displayed on the console
return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2]) return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2])
} }
@ -184,7 +184,7 @@ func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash
return nil, accounts.ErrWalletClosed return nil, accounts.ErrWalletClosed
} }
// Ensure the wallet is capable of signing the given transaction // Ensure the wallet is capable of signing the given transaction
if w.version[0] < 1 || (w.version[0] == 1 && w.version[1] < 5) { if w.version[0] < 1 && w.version[1] < 5 {
//lint:ignore ST1005 brand name displayed on the console //lint:ignore ST1005 brand name displayed on the console
return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2]) return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2])
} }

View file

@ -632,7 +632,7 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID
// data is not supported for Ledger wallets, so this method will always return // data is not supported for Ledger wallets, so this method will always return
// an error. // an error.
func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {
return w.SignText(account, text) return w.SignText(account, accounts.TextHash(text))
} }
// SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given

View file

@ -2,6 +2,7 @@ clone_depth: 5
version: "{branch}.{build}" version: "{branch}.{build}"
image: image:
- Ubuntu
- Visual Studio 2019 - Visual Studio 2019
environment: environment:
@ -16,6 +17,25 @@ install:
- go version - go version
for: for:
# Linux has its own script without -arch and -cc.
# The linux builder also runs lint.
- matrix:
only:
- image: Ubuntu
build_script:
- go run build/ci.go lint
- go run build/ci.go check_generate
- go run build/ci.go check_baddeps
- go run build/ci.go install -dlgo
test_script:
- go run build/ci.go test -dlgo -short
# linux/386 is disabled.
- matrix:
exclude:
- image: Ubuntu
GETH_ARCH: 386
# Windows builds for amd64 + 386. # Windows builds for amd64 + 386.
- matrix: - matrix:
only: only:

View file

@ -32,7 +32,7 @@ var (
testServer2 = testServer("testServer2") testServer2 = testServer("testServer2")
testBlock1 = types.NewBeaconBlock(&deneb.BeaconBlock{ testBlock1 = types.NewBeaconBlock(&deneb.BeaconBlock{
Slot: 127, Slot: 123,
Body: deneb.BeaconBlockBody{ Body: deneb.BeaconBlockBody{
ExecutionPayload: deneb.ExecutionPayload{ ExecutionPayload: deneb.ExecutionPayload{
BlockNumber: 456, BlockNumber: 456,
@ -41,7 +41,7 @@ var (
}, },
}) })
testBlock2 = types.NewBeaconBlock(&deneb.BeaconBlock{ testBlock2 = types.NewBeaconBlock(&deneb.BeaconBlock{
Slot: 128, Slot: 124,
Body: deneb.BeaconBlockBody{ Body: deneb.BeaconBlockBody{
ExecutionPayload: deneb.ExecutionPayload{ ExecutionPayload: deneb.ExecutionPayload{
BlockNumber: 457, BlockNumber: 457,
@ -49,14 +49,6 @@ var (
}, },
}, },
}) })
testFinal1 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
BlockNumber: 395,
BlockHash: zrntcommon.Hash32(common.HexToHash("abbe7625624bf8ddd84723709e2758956289465dd23475f02387e0854942666")),
})
testFinal2 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{
BlockNumber: 420,
BlockHash: zrntcommon.Hash32(common.HexToHash("9182a6ef8723654de174283750932ccc092378549836bf4873657eeec474598")),
})
) )
type testServer string type testServer string
@ -74,10 +66,9 @@ func TestBlockSync(t *testing.T) {
ts.AddServer(testServer1, 1) ts.AddServer(testServer1, 1)
ts.AddServer(testServer2, 1) ts.AddServer(testServer2, 1)
expHeadEvent := func(expHead *types.BeaconBlock, expFinal *types.ExecutionHeader) { expHeadBlock := func(expHead *types.BeaconBlock) {
t.Helper() t.Helper()
var expNumber, headNumber uint64 var expNumber, headNumber uint64
var expFinalHash, finalHash common.Hash
if expHead != nil { if expHead != nil {
p, err := expHead.ExecutionPayload() p, err := expHead.ExecutionPayload()
if err != nil { if err != nil {
@ -85,26 +76,19 @@ func TestBlockSync(t *testing.T) {
} }
expNumber = p.NumberU64() expNumber = p.NumberU64()
} }
if expFinal != nil {
expFinalHash = expFinal.BlockHash()
}
select { select {
case event := <-headCh: case event := <-headCh:
headNumber = event.Block.NumberU64() headNumber = event.Block.NumberU64()
finalHash = event.Finalized
default: default:
} }
if headNumber != expNumber { if headNumber != expNumber {
t.Errorf("Wrong head block, expected block number %d, got %d)", expNumber, headNumber) t.Errorf("Wrong head block, expected block number %d, got %d)", expNumber, headNumber)
} }
if finalHash != expFinalHash {
t.Errorf("Wrong finalized block, expected block hash %064x, got %064x)", expFinalHash[:], finalHash[:])
}
} }
// no block requests expected until head tracker knows about a head // no block requests expected until head tracker knows about a head
ts.Run(1) ts.Run(1)
expHeadEvent(nil, nil) expHeadBlock(nil)
// set block 1 as prefetch head, announced by server 2 // set block 1 as prefetch head, announced by server 2
head1 := blockHeadInfo(testBlock1) head1 := blockHeadInfo(testBlock1)
@ -119,13 +103,12 @@ func TestBlockSync(t *testing.T) {
ts.AddAllowance(testServer2, 1) ts.AddAllowance(testServer2, 1)
ts.Run(3) ts.Run(3)
// head block still not expected as the fetched block is not the validated head yet // head block still not expected as the fetched block is not the validated head yet
expHeadEvent(nil, nil) expHeadBlock(nil)
// set as validated head, expect no further requests but block 1 set as head block // set as validated head, expect no further requests but block 1 set as head block
ht.validated.Header = testBlock1.Header() ht.validated.Header = testBlock1.Header()
ht.finalized, ht.finalizedPayload = testBlock1.Header(), testFinal1
ts.Run(4) ts.Run(4)
expHeadEvent(testBlock1, testFinal1) expHeadBlock(testBlock1)
// set block 2 as prefetch head, announced by server 1 // set block 2 as prefetch head, announced by server 1
head2 := blockHeadInfo(testBlock2) head2 := blockHeadInfo(testBlock2)
@ -143,26 +126,17 @@ func TestBlockSync(t *testing.T) {
// expect req2 retry to server 2 // expect req2 retry to server 2
ts.Run(7, testServer2, sync.ReqBeaconBlock(head2.BlockRoot)) ts.Run(7, testServer2, sync.ReqBeaconBlock(head2.BlockRoot))
// now head block should be unavailable again // now head block should be unavailable again
expHeadEvent(nil, nil) expHeadBlock(nil)
// valid response, now head block should be block 2 immediately as it is already validated // valid response, now head block should be block 2 immediately as it is already validated
// but head event is still not expected because an epoch boundary was crossed and the
// expected finality update has not arrived yet
ts.RequestEvent(request.EvResponse, ts.Request(7, 1), testBlock2) ts.RequestEvent(request.EvResponse, ts.Request(7, 1), testBlock2)
ts.Run(8) ts.Run(8)
expHeadEvent(nil, nil) expHeadBlock(testBlock2)
// expected finality update arrived, now a head event is expected
ht.finalized, ht.finalizedPayload = testBlock2.Header(), testFinal2
ts.Run(9)
expHeadEvent(testBlock2, testFinal2)
} }
type testHeadTracker struct { type testHeadTracker struct {
prefetch types.HeadInfo prefetch types.HeadInfo
validated types.SignedHeader validated types.SignedHeader
finalized types.Header
finalizedPayload *types.ExecutionHeader
} }
func (h *testHeadTracker) PrefetchHead() types.HeadInfo { func (h *testHeadTracker) PrefetchHead() types.HeadInfo {
@ -177,14 +151,13 @@ func (h *testHeadTracker) ValidatedOptimistic() (types.OptimisticUpdate, bool) {
}, h.validated.Header != (types.Header{}) }, h.validated.Header != (types.Header{})
} }
// TODO add test case for finality
func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) { func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) {
if h.validated.Header == (types.Header{}) || h.finalizedPayload == nil { finalized := types.NewExecutionHeader(new(deneb.ExecutionPayloadHeader))
return types.FinalityUpdate{}, false
}
return types.FinalityUpdate{ return types.FinalityUpdate{
Attested: types.HeaderWithExecProof{Header: h.finalized}, Attested: types.HeaderWithExecProof{Header: h.validated.Header},
Finalized: types.HeaderWithExecProof{Header: h.finalized, PayloadHeader: h.finalizedPayload}, Finalized: types.HeaderWithExecProof{PayloadHeader: finalized},
Signature: h.validated.Signature, Signature: h.validated.Signature,
SignatureSlot: h.validated.SignatureSlot, SignatureSlot: h.validated.SignatureSlot,
}, true }, h.validated.Header != (types.Header{})
} }

View file

@ -87,10 +87,6 @@ func (ec *engineClient) updateLoop(headCh <-chan types.ChainHeadEvent) {
if status, err := ec.callForkchoiceUpdated(forkName, event); err == nil { if status, err := ec.callForkchoiceUpdated(forkName, event); err == nil {
log.Info("Successful ForkchoiceUpdated", "head", event.Block.Hash(), "status", status) log.Info("Successful ForkchoiceUpdated", "head", event.Block.Hash(), "status", status)
} else { } else {
if err.Error() == "beacon syncer reorging" {
log.Debug("Failed ForkchoiceUpdated", "head", event.Block.Hash(), "error", err)
continue // ignore beacon syncer reorging errors, this error can occur if the blsync is skipping a block
}
log.Error("Failed ForkchoiceUpdated", "head", event.Block.Hash(), "error", err) log.Error("Failed ForkchoiceUpdated", "head", event.Block.Hash(), "error", err)
} }
} }
@ -105,16 +101,7 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent)
params = []any{execData} params = []any{execData}
) )
switch fork { switch fork {
case "altair", "bellatrix": case "electra":
method = "engine_newPayloadV1"
case "capella":
method = "engine_newPayloadV2"
case "deneb":
method = "engine_newPayloadV3"
parentBeaconRoot := event.BeaconHead.ParentRoot
blobHashes := collectBlobHashes(event.Block)
params = append(params, blobHashes, parentBeaconRoot)
default: // electra, fulu and above
method = "engine_newPayloadV4" method = "engine_newPayloadV4"
parentBeaconRoot := event.BeaconHead.ParentRoot parentBeaconRoot := event.BeaconHead.ParentRoot
blobHashes := collectBlobHashes(event.Block) blobHashes := collectBlobHashes(event.Block)
@ -123,6 +110,15 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent)
hexRequests[i] = hexutil.Bytes(event.ExecRequests[i]) hexRequests[i] = hexutil.Bytes(event.ExecRequests[i])
} }
params = append(params, blobHashes, parentBeaconRoot, hexRequests) params = append(params, blobHashes, parentBeaconRoot, hexRequests)
case "deneb":
method = "engine_newPayloadV3"
parentBeaconRoot := event.BeaconHead.ParentRoot
blobHashes := collectBlobHashes(event.Block)
params = append(params, blobHashes, parentBeaconRoot)
case "capella":
method = "engine_newPayloadV2"
default:
method = "engine_newPayloadV1"
} }
ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5) ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5)
@ -149,12 +145,12 @@ func (ec *engineClient) callForkchoiceUpdated(fork string, event types.ChainHead
var method string var method string
switch fork { switch fork {
case "altair", "bellatrix": case "deneb", "electra":
method = "engine_forkchoiceUpdatedV1" method = "engine_forkchoiceUpdatedV3"
case "capella": case "capella":
method = "engine_forkchoiceUpdatedV2" method = "engine_forkchoiceUpdatedV2"
default: // deneb, electra, fulu and above default:
method = "engine_forkchoiceUpdatedV3" method = "engine_forkchoiceUpdatedV1"
} }
ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5) ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5)

View file

@ -21,7 +21,6 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"` Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
} }
var enc PayloadAttributes var enc PayloadAttributes
enc.Timestamp = hexutil.Uint64(p.Timestamp) enc.Timestamp = hexutil.Uint64(p.Timestamp)
@ -29,7 +28,6 @@ func (p PayloadAttributes) MarshalJSON() ([]byte, error) {
enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient enc.SuggestedFeeRecipient = p.SuggestedFeeRecipient
enc.Withdrawals = p.Withdrawals enc.Withdrawals = p.Withdrawals
enc.BeaconRoot = p.BeaconRoot enc.BeaconRoot = p.BeaconRoot
enc.SlotNumber = (*hexutil.Uint64)(p.SlotNumber)
return json.Marshal(&enc) return json.Marshal(&enc)
} }
@ -41,7 +39,6 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
SuggestedFeeRecipient *common.Address `json:"suggestedFeeRecipient" gencodec:"required"` SuggestedFeeRecipient *common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"` Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *hexutil.Uint64 `json:"slotNumber"`
} }
var dec PayloadAttributes var dec PayloadAttributes
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
@ -65,8 +62,5 @@ func (p *PayloadAttributes) UnmarshalJSON(input []byte) error {
if dec.BeaconRoot != nil { if dec.BeaconRoot != nil {
p.BeaconRoot = dec.BeaconRoot p.BeaconRoot = dec.BeaconRoot
} }
if dec.SlotNumber != nil {
p.SlotNumber = (*uint64)(dec.SlotNumber)
}
return nil return nil
} }

View file

@ -17,24 +17,24 @@ 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"`
SlotNumber *hexutil.Uint64 `json:"slotNumber"` ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
} }
var enc ExecutableData var enc ExecutableData
enc.ParentHash = e.ParentHash enc.ParentHash = e.ParentHash
@ -59,31 +59,31 @@ 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.SlotNumber = (*hexutil.Uint64)(e.SlotNumber) 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"`
SlotNumber *hexutil.Uint64 `json:"slotNumber"` 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 {
@ -157,8 +157,8 @@ 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.SlotNumber != nil { if dec.ExecutionWitness != nil {
e.SlotNumber = (*uint64)(dec.SlotNumber) e.ExecutionWitness = dec.ExecutionWitness
} }
return nil return nil
} }

View file

@ -17,7 +17,7 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
type ExecutionPayloadEnvelope struct { type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundle `json:"blobsBundle"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Requests []hexutil.Bytes `json:"executionRequests"` Requests []hexutil.Bytes `json:"executionRequests"`
Override bool `json:"shouldOverrideBuilder"` Override bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness,omitempty"` Witness *hexutil.Bytes `json:"witness,omitempty"`
@ -42,7 +42,7 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
type ExecutionPayloadEnvelope struct { type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundle `json:"blobsBundle"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Requests []hexutil.Bytes `json:"executionRequests"` Requests []hexutil.Bytes `json:"executionRequests"`
Override *bool `json:"shouldOverrideBuilder"` Override *bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness,omitempty"` Witness *hexutil.Bytes `json:"witness,omitempty"`

View file

@ -33,30 +33,9 @@ import (
type PayloadVersion byte type PayloadVersion byte
var ( var (
// PayloadV1 is the identifier of ExecutionPayloadV1 introduced in paris fork.
// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#executionpayloadv1
PayloadV1 PayloadVersion = 0x1 PayloadV1 PayloadVersion = 0x1
// PayloadV2 is the identifier of ExecutionPayloadV2 introduced in shanghai fork.
//
// https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#executionpayloadv2
// ExecutionPayloadV2 has the syntax of ExecutionPayloadV1 and appends a
// single field: withdrawals.
PayloadV2 PayloadVersion = 0x2 PayloadV2 PayloadVersion = 0x2
// PayloadV3 is the identifier of ExecutionPayloadV3 introduced in cancun fork.
//
// https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#executionpayloadv3
// ExecutionPayloadV3 has the syntax of ExecutionPayloadV2 and appends the new
// fields: blobGasUsed and excessBlobGas.
PayloadV3 PayloadVersion = 0x3 PayloadV3 PayloadVersion = 0x3
// PayloadV4 is the identifier of ExecutionPayloadV4 introduced in amsterdam fork.
//
// https://github.com/ethereum/execution-apis/blob/main/src/engine/amsterdam.md#executionpayloadv4
// ExecutionPayloadV4 has the syntax of ExecutionPayloadV3 and appends the new
// field slotNumber.
PayloadV4 PayloadVersion = 0x4
) )
//go:generate go run github.com/fjl/gencodec -type PayloadAttributes -field-override payloadAttributesMarshaling -out gen_blockparams.go //go:generate go run github.com/fjl/gencodec -type PayloadAttributes -field-override payloadAttributesMarshaling -out gen_blockparams.go
@ -69,37 +48,35 @@ type PayloadAttributes struct {
SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"` SuggestedFeeRecipient common.Address `json:"suggestedFeeRecipient" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"` Withdrawals []*types.Withdrawal `json:"withdrawals"`
BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"` BeaconRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *uint64 `json:"slotNumber"`
} }
// JSON type overrides for PayloadAttributes. // JSON type overrides for PayloadAttributes.
type payloadAttributesMarshaling struct { type payloadAttributesMarshaling struct {
Timestamp hexutil.Uint64 Timestamp hexutil.Uint64
SlotNumber *hexutil.Uint64
} }
//go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go //go:generate go run github.com/fjl/gencodec -type ExecutableData -field-override executableDataMarshaling -out gen_ed.go
// 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"`
SlotNumber *uint64 `json:"slotNumber"` ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
} }
// JSON type overrides for executableData. // JSON type overrides for executableData.
@ -114,7 +91,6 @@ type executableDataMarshaling struct {
Transactions []hexutil.Bytes Transactions []hexutil.Bytes
BlobGasUsed *hexutil.Uint64 BlobGasUsed *hexutil.Uint64
ExcessBlobGas *hexutil.Uint64 ExcessBlobGas *hexutil.Uint64
SlotNumber *hexutil.Uint64
} }
// StatelessPayloadStatusV1 is the result of a stateless payload execution. // StatelessPayloadStatusV1 is the result of a stateless payload execution.
@ -130,18 +106,13 @@ type StatelessPayloadStatusV1 struct {
type ExecutionPayloadEnvelope struct { type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *big.Int `json:"blockValue" gencodec:"required"` BlockValue *big.Int `json:"blockValue" gencodec:"required"`
BlobsBundle *BlobsBundle `json:"blobsBundle"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
Requests [][]byte `json:"executionRequests"` Requests [][]byte `json:"executionRequests"`
Override bool `json:"shouldOverrideBuilder"` Override bool `json:"shouldOverrideBuilder"`
Witness *hexutil.Bytes `json:"witness,omitempty"` Witness *hexutil.Bytes `json:"witness,omitempty"`
} }
// BlobsBundle includes the marshalled sidecar data. Note this structure is type BlobsBundleV1 struct {
// shared by BlobsBundleV1 and BlobsBundleV2 for the sake of simplicity.
//
// - BlobsBundleV1: proofs contain exactly len(blobs) kzg proofs.
// - BlobsBundleV2: proofs contain exactly CELLS_PER_EXT_BLOB * len(blobs) cell proofs.
type BlobsBundle struct {
Commitments []hexutil.Bytes `json:"commitments"` Commitments []hexutil.Bytes `json:"commitments"`
Proofs []hexutil.Bytes `json:"proofs"` Proofs []hexutil.Bytes `json:"proofs"`
Blobs []hexutil.Bytes `json:"blobs"` Blobs []hexutil.Bytes `json:"blobs"`
@ -154,7 +125,7 @@ type BlobAndProofV1 struct {
type BlobAndProofV2 struct { type BlobAndProofV2 struct {
Blob hexutil.Bytes `json:"blob"` Blob hexutil.Bytes `json:"blob"`
CellProofs []hexutil.Bytes `json:"proofs"` // proofs MUST contain exactly CELLS_PER_EXT_BLOB cell proofs. CellProofs []hexutil.Bytes `json:"proofs"`
} }
// JSON type overrides for ExecutionPayloadEnvelope. // JSON type overrides for ExecutionPayloadEnvelope.
@ -224,7 +195,7 @@ func encodeTransactions(txs []*types.Transaction) [][]byte {
return enc return enc
} }
func DecodeTransactions(enc [][]byte) ([]*types.Transaction, error) { func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
var txs = make([]*types.Transaction, len(enc)) var txs = make([]*types.Transaction, len(enc))
for i, encTx := range enc { for i, encTx := range enc {
var tx types.Transaction var tx types.Transaction
@ -262,7 +233,7 @@ func ExecutableDataToBlock(data ExecutableData, versionedHashes []common.Hash, b
// for stateless execution, so it skips checking if the executable data hashes to // 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). // the requested hash (stateless has to *compute* the root hash, it's not given).
func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte) (*types.Block, error) { func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash, requests [][]byte) (*types.Block, error) {
txs, err := DecodeTransactions(data.Transactions) txs, err := decodeTransactions(data.Transactions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -324,10 +295,10 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
BlobGasUsed: data.BlobGasUsed, BlobGasUsed: data.BlobGasUsed,
ParentBeaconRoot: beaconRoot, ParentBeaconRoot: beaconRoot,
RequestsHash: requestsHash, RequestsHash: requestsHash,
SlotNumber: data.SlotNumber,
} }
return types.NewBlockWithHeader(header). return types.NewBlockWithHeader(header).
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}), WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}).
WithWitness(data.ExecutionWitness),
nil nil
} }
@ -335,48 +306,39 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
// 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, requests [][]byte) *ExecutionPayloadEnvelope { func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar, requests [][]byte) *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(),
SlotNumber: block.SlotNumber(), ExecutionWitness: block.ExecutionWitness(),
} }
// Add blobs. // Add blobs.
bundle := BlobsBundle{ bundle := BlobsBundleV1{
Commitments: make([]hexutil.Bytes, 0), Commitments: make([]hexutil.Bytes, 0),
Blobs: make([]hexutil.Bytes, 0), Blobs: make([]hexutil.Bytes, 0),
Proofs: make([]hexutil.Bytes, 0), Proofs: make([]hexutil.Bytes, 0),
} }
for _, sidecar := range sidecars { for _, sidecar := range sidecars {
for j := range sidecar.Blobs { for j := range sidecar.Blobs {
bundle.Blobs = append(bundle.Blobs, sidecar.Blobs[j][:]) bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:]))
bundle.Commitments = append(bundle.Commitments, sidecar.Commitments[j][:]) bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:]))
} }
// - Before the Osaka fork, only version-0 blob transactions should be packed,
// with the proof length equal to len(blobs).
//
// - After the Osaka fork, only version-1 blob transactions should be packed,
// with the proof length equal to CELLS_PER_EXT_BLOB * len(blobs).
//
// Ideally, length validation should be performed based on the bundle version.
// In practice, this is unnecessary because blob transaction filtering is
// already done during payload construction.
for _, proof := range sidecar.Proofs { for _, proof := range sidecar.Proofs {
bundle.Proofs = append(bundle.Proofs, proof[:]) bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(proof[:]))
} }
} }

View file

@ -69,10 +69,7 @@ func newCanonicalStore[T any](db ethdb.Iteratee, keyPrefix []byte) (*canonicalSt
// databaseKey returns the database key belonging to the given period. // databaseKey returns the database key belonging to the given period.
func (cs *canonicalStore[T]) databaseKey(period uint64) []byte { func (cs *canonicalStore[T]) databaseKey(period uint64) []byte {
key := make([]byte, len(cs.keyPrefix)+8) return binary.BigEndian.AppendUint64(append([]byte{}, cs.keyPrefix...), period)
copy(key, cs.keyPrefix)
binary.BigEndian.PutUint64(key[len(cs.keyPrefix):], period)
return key
} }
// add adds the given item to the database. It also ensures that the range remains // add adds the given item to the database. It also ensures that the range remains

View file

@ -269,7 +269,7 @@ func (s *Scheduler) addEvent(event Event) {
s.Trigger() s.Trigger()
} }
// filterEvents sorts each Event either as a request event or a server event, // filterEvent sorts each Event either as a request event or a server event,
// depending on its type. Request events are also sorted in a map based on the // depending on its type. Request events are also sorted in a map based on the
// module that originally initiated the request. It also ensures that no events // module that originally initiated the request. It also ensures that no events
// related to a server are returned before EvRegistered or after EvUnregistered. // related to a server are returned before EvRegistered or after EvUnregistered.

View file

@ -105,7 +105,6 @@ func (s *HeadSync) Process(requester request.Requester, events []request.Event)
delete(s.serverHeads, event.Server) delete(s.serverHeads, event.Server)
delete(s.unvalidatedOptimistic, event.Server) delete(s.unvalidatedOptimistic, event.Server)
delete(s.unvalidatedFinality, event.Server) delete(s.unvalidatedFinality, event.Server)
delete(s.reqFinalityEpoch, event.Server)
} }
} }
} }

View file

@ -32,7 +32,7 @@ type Value [32]byte
// Values represent a series of merkle tree leaves/nodes. // Values represent a series of merkle tree leaves/nodes.
type Values []Value type Values []Value
var valueT = reflect.TypeFor[Value]() var valueT = reflect.TypeOf(Value{})
// UnmarshalJSON parses a merkle value in hex syntax. // UnmarshalJSON parses a merkle value in hex syntax.
func (m *Value) UnmarshalJSON(input []byte) error { func (m *Value) UnmarshalJSON(input []byte) error {

View file

@ -1 +1 @@
0xbb7a7f3c40d8ea0b450f91587db65d0f1c079669277e01a0426c8911702a863a 0x1bbf958008172591b6cbdb3d8d52e26998258e83d4bdb9eec10969d84519a6bd

View file

@ -1 +1 @@
0x2af778d703186526a1b6304b423f338f11556206f618643c3f7fa0d7b1ef5c9b 0x2fe39a39b6f7cbd549e0f74d259de6db486005a65bd3bd92840dd6ce21d6f4c8

View file

@ -1 +1 @@
0x48a89c9ea7ba19de2931797974cf8722344ab231c0edada278b108ef74125478 0x86686b2b366e24134e0e3969a9c5f3759f92e5d2b04785b42e22cc7d468c2107

View file

@ -20,7 +20,6 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"math" "math"
"math/big"
"os" "os"
"slices" "slices"
"sort" "sort"
@ -38,7 +37,7 @@ import (
// across signing different data structures. // across signing different data structures.
const syncCommitteeDomain = 7 const syncCommitteeDomain = 7
var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB", "ELECTRA", "FULU"} var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"}
// ClientConfig contains beacon light client configuration. // ClientConfig contains beacon light client configuration.
type ClientConfig struct { type ClientConfig struct {
@ -91,8 +90,12 @@ func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainC
// LoadForks parses the beacon chain configuration file (config.yaml) and extracts // LoadForks parses the beacon chain configuration file (config.yaml) and extracts
// the list of forks. // the list of forks.
func (c *ChainConfig) LoadForks(file []byte) error { func (c *ChainConfig) LoadForks(path string) error {
config := make(map[string]any) file, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read beacon chain config file: %v", err)
}
config := make(map[string]string)
if err := yaml.Unmarshal(file, &config); err != nil { if err := yaml.Unmarshal(file, &config); err != nil {
return fmt.Errorf("failed to parse beacon chain config file: %v", err) return fmt.Errorf("failed to parse beacon chain config file: %v", err)
} }
@ -103,45 +106,20 @@ func (c *ChainConfig) LoadForks(file []byte) error {
epochs["GENESIS"] = 0 epochs["GENESIS"] = 0
for key, value := range config { for key, value := range config {
if value == nil {
continue
}
if strings.HasSuffix(key, "_FORK_VERSION") { if strings.HasSuffix(key, "_FORK_VERSION") {
name := key[:len(key)-len("_FORK_VERSION")] name := key[:len(key)-len("_FORK_VERSION")]
switch version := value.(type) { if v, err := hexutil.Decode(value); err == nil {
case int:
versions[name] = new(big.Int).SetUint64(uint64(version)).FillBytes(make([]byte, 4))
case int64:
versions[name] = new(big.Int).SetUint64(uint64(version)).FillBytes(make([]byte, 4))
case uint64:
versions[name] = new(big.Int).SetUint64(version).FillBytes(make([]byte, 4))
case string:
v, err := hexutil.Decode(version)
if err != nil {
return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", version, err)
}
versions[name] = v versions[name] = v
default: } else {
return fmt.Errorf("invalid fork version %q in beacon chain config file", version) return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", value, err)
} }
} }
if strings.HasSuffix(key, "_FORK_EPOCH") { if strings.HasSuffix(key, "_FORK_EPOCH") {
name := key[:len(key)-len("_FORK_EPOCH")] name := key[:len(key)-len("_FORK_EPOCH")]
switch epoch := value.(type) { if v, err := strconv.ParseUint(value, 10, 64); err == nil {
case int:
epochs[name] = uint64(epoch)
case int64:
epochs[name] = uint64(epoch)
case uint64:
epochs[name] = epoch
case string:
v, err := strconv.ParseUint(epoch, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", epoch, err)
}
epochs[name] = v epochs[name] = v
default: } else {
return fmt.Errorf("invalid fork epoch %q in beacon chain config file", epoch) return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", value, err)
} }
} }
} }

View file

@ -1,37 +0,0 @@
package params
import (
"bytes"
"testing"
)
func TestChainConfig_LoadForks(t *testing.T) {
const config = `
GENESIS_FORK_VERSION: 0x00000000
ALTAIR_FORK_VERSION: 0x00000001
ALTAIR_FORK_EPOCH: 1
EIP7928_FORK_VERSION: 0xb0000038
EIP7928_FORK_EPOCH: 18446744073709551615
EIP7XXX_FORK_VERSION:
EIP7XXX_FORK_EPOCH:
BLOB_SCHEDULE: []
`
c := &ChainConfig{}
err := c.LoadForks([]byte(config))
if err != nil {
t.Fatal(err)
}
for _, fork := range c.Forks {
if fork.Name == "GENESIS" && (fork.Epoch != 0) {
t.Errorf("unexpected genesis fork epoch %d", fork.Epoch)
}
if fork.Name == "ALTAIR" && (fork.Epoch != 1 || !bytes.Equal(fork.Version, []byte{0, 0, 0, 1})) {
t.Errorf("unexpected altair fork epoch %d version %x", fork.Epoch, fork.Version)
}
}
}

View file

@ -40,39 +40,36 @@ var (
GenesisTime: 1606824023, GenesisTime: 1606824023,
Checkpoint: common.HexToHash(checkpointMainnet), Checkpoint: common.HexToHash(checkpointMainnet),
}). }).
AddFork("GENESIS", 0, common.FromHex("0x00000000")). AddFork("GENESIS", 0, []byte{0, 0, 0, 0}).
AddFork("ALTAIR", 74240, common.FromHex("0x01000000")). AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}).
AddFork("BELLATRIX", 144896, common.FromHex("0x02000000")). AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}).
AddFork("CAPELLA", 194048, common.FromHex("0x03000000")). AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}).
AddFork("DENEB", 269568, common.FromHex("0x04000000")). AddFork("DENEB", 269568, []byte{4, 0, 0, 0}).
AddFork("ELECTRA", 364032, common.FromHex("0x05000000")). AddFork("ELECTRA", 364032, []byte{5, 0, 0, 0})
AddFork("FULU", 411392, common.FromHex("0x06000000"))
SepoliaLightConfig = (&ChainConfig{ SepoliaLightConfig = (&ChainConfig{
GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"), GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"),
GenesisTime: 1655733600, GenesisTime: 1655733600,
Checkpoint: common.HexToHash(checkpointSepolia), Checkpoint: common.HexToHash(checkpointSepolia),
}). }).
AddFork("GENESIS", 0, common.FromHex("0x90000069")). AddFork("GENESIS", 0, []byte{144, 0, 0, 105}).
AddFork("ALTAIR", 50, common.FromHex("0x90000070")). AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}).
AddFork("BELLATRIX", 100, common.FromHex("0x90000071")). AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}).
AddFork("CAPELLA", 56832, common.FromHex("0x90000072")). AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}).
AddFork("DENEB", 132608, common.FromHex("0x90000073")). AddFork("DENEB", 132608, []byte{144, 0, 0, 115}).
AddFork("ELECTRA", 222464, common.FromHex("0x90000074")). AddFork("ELECTRA", 222464, []byte{144, 0, 0, 116})
AddFork("FULU", 272640, common.FromHex("0x90000075"))
HoleskyLightConfig = (&ChainConfig{ HoleskyLightConfig = (&ChainConfig{
GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"),
GenesisTime: 1695902400, GenesisTime: 1695902400,
Checkpoint: common.HexToHash(checkpointHolesky), Checkpoint: common.HexToHash(checkpointHolesky),
}). }).
AddFork("GENESIS", 0, common.FromHex("0x01017000")). AddFork("GENESIS", 0, []byte{1, 1, 112, 0}).
AddFork("ALTAIR", 0, common.FromHex("0x02017000")). AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}).
AddFork("BELLATRIX", 0, common.FromHex("0x03017000")). AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}).
AddFork("CAPELLA", 256, common.FromHex("0x04017000")). AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
AddFork("DENEB", 29696, common.FromHex("0x05017000")). AddFork("DENEB", 29696, []byte{5, 1, 112, 0}).
AddFork("ELECTRA", 115968, common.FromHex("0x06017000")). AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0})
AddFork("FULU", 165120, common.FromHex("0x07017000"))
HoodiLightConfig = (&ChainConfig{ HoodiLightConfig = (&ChainConfig{
GenesisValidatorsRoot: common.HexToHash("0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f"), GenesisValidatorsRoot: common.HexToHash("0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f"),
@ -85,5 +82,5 @@ var (
AddFork("CAPELLA", 0, common.FromHex("0x40000910")). AddFork("CAPELLA", 0, common.FromHex("0x40000910")).
AddFork("DENEB", 0, common.FromHex("0x50000910")). AddFork("DENEB", 0, common.FromHex("0x50000910")).
AddFork("ELECTRA", 2048, common.FromHex("0x60000910")). AddFork("ELECTRA", 2048, common.FromHex("0x60000910")).
AddFork("FULU", 50688, common.FromHex("0x70000910")) AddFork("FULU", 18446744073709551615, common.FromHex("0x70000910"))
) )

View file

@ -52,7 +52,7 @@ func BlockFromJSON(forkName string, data []byte) (*BeaconBlock, error) {
obj = new(capella.BeaconBlock) obj = new(capella.BeaconBlock)
case "deneb": case "deneb":
obj = new(deneb.BeaconBlock) obj = new(deneb.BeaconBlock)
case "electra", "fulu": case "electra":
obj = new(electra.BeaconBlock) obj = new(electra.BeaconBlock)
default: default:
return nil, fmt.Errorf("unsupported fork: %s", forkName) return nil, fmt.Errorf("unsupported fork: %s", forkName)

View file

@ -45,7 +45,7 @@ func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, er
switch forkName { switch forkName {
case "capella": case "capella":
obj = new(capella.ExecutionPayloadHeader) obj = new(capella.ExecutionPayloadHeader)
case "deneb", "electra", "fulu": // note: the payload type was not changed in electra/fulu case "deneb", "electra": // note: the payload type was not changed in electra
obj = new(deneb.ExecutionPayloadHeader) obj = new(deneb.ExecutionPayloadHeader)
default: default:
return nil, fmt.Errorf("unsupported fork: %s", forkName) return nil, fmt.Errorf("unsupported fork: %s", forkName)

View file

@ -1,106 +1,113 @@
# This file contains sha256 checksums of optional build dependencies. # This file contains sha256 checksums of optional build dependencies.
# version:spec-tests v5.1.0 # version:spec-tests fusaka-devnet-3%40v1.0.0
# https://github.com/ethereum/execution-spec-tests/releases # https://github.com/ethereum/execution-spec-tests/releases
# https://github.com/ethereum/execution-spec-tests/releases/download/v5.1.0 # https://github.com/ethereum/execution-spec-tests/releases/download/fusaka-devnet-3%40v1.0.0
a3192784375acec7eaec492799d5c5d0c47a2909a3cc40178898e4ecd20cc416 fixtures_develop.tar.gz 576261e1280e5300c458aa9b05eccb2fec5ff80a0005940dc52fa03fdd907249 fixtures_fusaka-devnet-3.tar.gz
# version:golang 1.25.7 # version:golang 1.24.4
# https://go.dev/dl/ # https://go.dev/dl/
178f2832820274b43e177d32f06a3ebb0129e427dd20a5e4c88df2c1763cf10a go1.25.7.src.tar.gz 5a86a83a31f9fa81490b8c5420ac384fd3d95a3e71fba665c7b3f95d1dfef2b4 go1.24.4.src.tar.gz
81bf2a1f20633f62d55d826d82dde3b0570cf1408a91e15781b266037299285b go1.25.7.aix-ppc64.tar.gz 0d2af78e3b6e08f8013dbbdb26ae33052697b6b72e03ec17d496739c2a1aed68 go1.24.4.aix-ppc64.tar.gz
bf5050a2152f4053837b886e8d9640c829dbacbc3370f913351eb0904cb706f5 go1.25.7.darwin-amd64.tar.gz 69bef555e114b4a2252452b6e7049afc31fbdf2d39790b669165e89525cd3f5c go1.24.4.darwin-amd64.tar.gz
ff18369ffad05c57d5bed888b660b31385f3c913670a83ef557cdfd98ea9ae1b go1.25.7.darwin-arm64.tar.gz c4d74453a26f488bdb4b0294da4840d9020806de4661785334eb6d1803ee5c27 go1.24.4.darwin-amd64.pkg
c5dccd7f192dd7b305dc209fb316ac1917776d74bd8e4d532ef2772f305bf42a go1.25.7.dragonfly-amd64.tar.gz 27973684b515eaf461065054e6b572d9390c05e69ba4a423076c160165336470 go1.24.4.darwin-arm64.tar.gz
a2de97c8ac74bf64b0ae73fe9d379e61af530e061bc7f8f825044172ffe61a8b go1.25.7.freebsd-386.tar.gz 2fe1f8746745c4bfebd494583aaef24cad42594f6d25ed67856879d567ee66e7 go1.24.4.darwin-arm64.pkg
055f9e138787dcafa81eb0314c8ff70c6dd0f6dba1e8a6957fef5d5efd1ab8fd go1.25.7.freebsd-amd64.tar.gz 70b2de9c1cafe5af7be3eb8f80753cce0501ef300db3f3bd59be7ccc464234e1 go1.24.4.dragonfly-amd64.tar.gz
60e7f7a7c990f0b9539ac8ed668155746997d404643a4eecd47b3dee1b7e710b go1.25.7.freebsd-arm.tar.gz 8d529839db29ee171505b89dc9c3de76003a4ab56202d84bddbbecacbfb6d7c9 go1.24.4.freebsd-386.tar.gz
631e03d5fd4c526e2f499154d8c6bf4cb081afb2fff171c428722afc9539d53a go1.25.7.freebsd-arm64.tar.gz 6cbc3ad6cc21bdcc7283824d3ac0e85512c02022f6a35eb2e844882ea6e8448c go1.24.4.freebsd-amd64.tar.gz
8a264fd685823808140672812e3ad9c43f6ad59444c0dc14cdd3a1351839ddd5 go1.25.7.freebsd-riscv64.tar.gz d49ae050c20aff646a7641dd903f03eb674570790b90ffb298076c4d41e36655 go1.24.4.freebsd-arm.tar.gz
57c672447d906a1bcab98f2b11492d54521a791aacbb4994a25169e59cbe289a go1.25.7.illumos-amd64.tar.gz e31924abef2a28456b7103c0a5d333dcc11ecf19e76d5de1a383ad5fe0b42457 go1.24.4.freebsd-arm64.tar.gz
2866517e9ca81e6a2e85a930e9b11bc8a05cfeb2fc6dc6cb2765e7fb3c14b715 go1.25.7.linux-386.tar.gz b5bca135eae8ebddf22972611ac1c58ae9fbb5979fd953cc5245c5b1b2517546 go1.24.4.freebsd-riscv64.tar.gz
12e6d6a191091ae27dc31f6efc630e3a3b8ba409baf3573d955b196fdf086005 go1.25.7.linux-amd64.tar.gz 7d5efda511ff7e3114b130acee5d0bffbb078fedbfa9b2c1b6a807107e1ca23a go1.24.4.illumos-amd64.tar.gz
ba611a53534135a81067240eff9508cd7e256c560edd5d8c2fef54f083c07129 go1.25.7.linux-arm64.tar.gz 130c9b061082eca15513e595e9952a2ded32e737e609dd0e49f7dfa74eba026d go1.24.4.linux-386.tar.gz
1ba07e0eb86b839e72467f4b5c7a5597d07f30bcf5563c951410454f7cda5266 go1.25.7.linux-armv6l.tar.gz 77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717 go1.24.4.linux-amd64.tar.gz
775753fc5952a334c415f08768df2f0b73a3228a16e8f5f63d545daacb4e3357 go1.25.7.linux-loong64.tar.gz d5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241 go1.24.4.linux-arm64.tar.gz
1a023bb367c5fbb4c637a2f6dc23ff17c6591ad929ce16ea88c74d857153b307 go1.25.7.linux-mips.tar.gz 6a554e32301cecae3162677e66d4264b81b3b1a89592dd1b7b5c552c7a49fe37 go1.24.4.linux-armv6l.tar.gz
a8e97223d8aa6fdfd45f132a4784d2f536bbac5f3d63a24b63d33b6bfe1549af go1.25.7.linux-mips64.tar.gz b208eb25fe244408cbe269ed426454bc46e59d0e0a749b6240d39e884e969875 go1.24.4.linux-loong64.tar.gz
eb9edb6223330d5e20275667c65dea076b064c08e595fe4eba5d7d6055cfaccf go1.25.7.linux-mips64le.tar.gz fddfcb28fd36fe63d2ae181026798f86f3bbd3a7bb0f1e1f617dd3d604bf3fe4 go1.24.4.linux-mips.tar.gz
9c1e693552a5f9bb9e0012d1c5e01456ecefbc59bef53a77305222ce10aba368 go1.25.7.linux-mipsle.tar.gz 7934b924d5ab8c8ae3134a09a6ae74d3c39f63f6c4322ec289364dbbf0bac3ca go1.24.4.linux-mips64.tar.gz
28a788798e7329acbbc0ac2caa5e4368b1e5ede646cc24429c991214cfb45c63 go1.25.7.linux-ppc64.tar.gz fa763d8673f94d6e534bb72c3cf675d4c2b8da4a6da42a89f08c5586106db39c go1.24.4.linux-mips64le.tar.gz
42124c0edc92464e2b37b2d7fcd3658f0c47ebd6a098732415a522be8cb88e3f go1.25.7.linux-ppc64le.tar.gz 84363dbfe49b41d43df84420a09bd53a4770053d63bfa509868c46a5f8eb3ff7 go1.24.4.linux-mipsle.tar.gz
88d59c6893c8425875d6eef8e3434bc2fa2552e5ad4c058c6cd8cd710a0301c8 go1.25.7.linux-riscv64.tar.gz 28fcbd5d3b56493606873c33f2b4bdd84ba93c633f37313613b5a1e6495c6fe5 go1.24.4.linux-ppc64.tar.gz
c6b77facf666dc68195ecab05dbf0ebb4e755b2a8b7734c759880557f1c29b0c go1.25.7.linux-s390x.tar.gz 9ca4afef813a2578c23843b640ae0290aa54b2e3c950a6cc4c99e16a57dec2ec go1.24.4.linux-ppc64le.tar.gz
f14c184d9ade0ee04c7735d4071257b90896ecbde1b32adae84135f055e6399b go1.25.7.netbsd-386.tar.gz 1d7034f98662d8f2c8abd7c700ada4093acb4f9c00e0e51a30344821d0785c77 go1.24.4.linux-riscv64.tar.gz
7e7389e404dca1088c31f0fc07f1dd60891d7182bcd621469c14f7e79eceb3ff go1.25.7.netbsd-amd64.tar.gz 0449f3203c39703ab27684be763e9bb78ca9a051e0e4176727aead9461b6deb5 go1.24.4.linux-s390x.tar.gz
70388bb3ef2f03dbf1357e9056bd09034a67e018262557354f8cf549766b3f9d go1.25.7.netbsd-arm.tar.gz 954b49ccc2cfcf4b5f7cd33ff662295e0d3b74e7590c8e25fc2abb30bce120ba go1.24.4.netbsd-386.tar.gz
8c1cda9d25bfc9b18d24d5f95fc23949dd3ff99fa408a6cfa40e2cf12b07e362 go1.25.7.netbsd-arm64.tar.gz 370fabcdfee7c18857c96fdd5b706e025d4fb86a208da88ba56b1493b35498e9 go1.24.4.netbsd-amd64.tar.gz
42f0d1bfbe39b8401cccb84dd66b30795b97bfc9620dfdc17c5cd4fcf6495cb0 go1.25.7.openbsd-386.tar.gz 7935ef95d4d1acc48587b1eb4acab98b0a7d9569736a32398b9c1d2e89026865 go1.24.4.netbsd-arm.tar.gz
e514879c0a28bc32123cd52c4c093de912477fe83f36a6d07517d066ef55391a go1.25.7.openbsd-amd64.tar.gz ead78fd0fa29fbb176cc83f1caa54032e1a44f842affa56a682c647e0759f237 go1.24.4.netbsd-arm64.tar.gz
8cd22530695a0218232bf7efea8f162df1697a3106942ac4129b8c3de39ce4ef go1.25.7.openbsd-arm.tar.gz 913e217394b851a636b99de175f0c2f9ab9938b41c557f047168f77ee485d776 go1.24.4.openbsd-386.tar.gz
938720f6ebc0d1c53d7840321d3a31f29fd02496e84a6538f442a9311dc1cc9a go1.25.7.openbsd-arm64.tar.gz 24568da3dcbcdb24ec18b631f072faf0f3763e3d04f79032dc56ad9ec35379c4 go1.24.4.openbsd-amd64.tar.gz
a4c378b73b98f89a3596c2ef51aabbb28783d9ca29f7e317d8ca07939660ce6f go1.25.7.openbsd-ppc64.tar.gz 45abf523f870632417ab007de3841f64dd906bde546ffc8c6380ccbe91c7fb73 go1.24.4.openbsd-arm.tar.gz
937b58734fbeaa8c7941a0e4285e7e84b7885396e8d11c23f9ab1a8ff10ff20e go1.25.7.openbsd-riscv64.tar.gz 7c57c69b5dd1e946b28a3034c285240a48e2861bdcb50b7d9c0ed61bcf89c879 go1.24.4.openbsd-arm64.tar.gz
61a093c8c5244916f25740316386bb9f141545dcf01b06a79d1c78ece488403e go1.25.7.plan9-386.tar.gz 91ed711f704829372d6931e1897631ef40288b8f9e3cd6ef4a24df7126d1066a go1.24.4.openbsd-ppc64.tar.gz
7fc8f6689c9de8ccb7689d2278035fa83c2d601409101840df6ddfe09ba58699 go1.25.7.plan9-amd64.tar.gz de5e270d971c8790e8880168d56a2ea103979927c10ded136d792bbdf9bce3d3 go1.24.4.openbsd-riscv64.tar.gz
9661dff8eaeeb62f1c3aadbc5ff189a2e6744e1ec885e32dbcb438f58a34def5 go1.25.7.plan9-arm.tar.gz ff429d03f00bcd32a50f445320b8329d0fadb2a2fff899c11e95e0922a82c543 go1.24.4.plan9-386.tar.gz
28ecba0e1d7950c8b29a4a04962dd49c3bf5221f55a44f17d98f369f82859cf4 go1.25.7.solaris-amd64.tar.gz 39d6363a43fd16b60ae9ad7346a264e982e4fa653dee3b45f83e03cd2f7a6647 go1.24.4.plan9-amd64.tar.gz
baa6b488291801642fa620026169e38bec2da2ac187cd3ae2145721cf826bbc3 go1.25.7.windows-386.zip 1964ae2571259de77b930e97f2891aa92706ff81aac9909d45bb107b0fab16c8 go1.24.4.plan9-arm.tar.gz
c75e5f4ff62d085cc0017be3ad19d5536f46825fa05db06ec468941f847e3228 go1.25.7.windows-amd64.zip a7f9af424e8fb87886664754badca459513f64f6a321d17f1d219b8edf519821 go1.24.4.solaris-amd64.tar.gz
807033f85931bc4a589ca8497535dcbeb1f30d506e47fa200f5f04c4a71c3d9f go1.25.7.windows-arm64.zip d454d3cb144432f1726bf00e28c6017e78ccb256a8d01b8e3fb1b2e6b5650f28 go1.24.4.windows-386.zip
966ecace1cdbb3497a2b930bdb0f90c3ad32922fa1a7c655b2d4bbeb7e4ac308 go1.24.4.windows-386.msi
b751a1136cb9d8a2e7ebb22c538c4f02c09b98138c7c8bfb78a54a4566c013b1 go1.24.4.windows-amd64.zip
0cbb6e83865747dbe69b3d4155f92e88fcf336ff5d70182dba145e9d7bd3d8f6 go1.24.4.windows-amd64.msi
d17da51bc85bd010754a4063215d15d2c033cc289d67ca9201a03c9041b2969d go1.24.4.windows-arm64.zip
47dbe734b6a829de45654648a7abcf05bdceef5c80e03ea0b208eeebef75a852 go1.24.4.windows-arm64.msi
# version:golangci 2.10.1 # version:golangci 2.0.2
# https://github.com/golangci/golangci-lint/releases/ # https://github.com/golangci/golangci-lint/releases/
# https://github.com/golangci/golangci-lint/releases/download/v2.10.1 # https://github.com/golangci/golangci-lint/releases/download/v2.0.2/
66fb0da81b8033b477f97eea420d4b46b230ca172b8bb87c6610109f3772b6b6 golangci-lint-2.10.1-darwin-amd64.tar.gz a88cbdc86b483fe44e90bf2dcc3fec2af8c754116e6edf0aa6592cac5baa7a0e golangci-lint-2.0.2-darwin-amd64.tar.gz
03bfadf67e52b441b7ec21305e501c717df93c959836d66c7f97312654acb297 golangci-lint-2.10.1-darwin-arm64.tar.gz 664550e7954f5f4451aae99b4f7382c1a47039c66f39ca605f5d9af1a0d32b49 golangci-lint-2.0.2-darwin-arm64.tar.gz
c9a44658ccc8f7b8dbbd4ae6020ba91c1a5d3987f4d91ced0f7d2bea013e57ca golangci-lint-2.10.1-freebsd-386.tar.gz bda0f0f27d300502faceda8428834a76ca25986f6d9fc2bd41d201c3ed73f08e golangci-lint-2.0.2-freebsd-386.tar.gz
a513c5cb4e0f5bd5767001af9d5e97e7868cfc2d9c46739a4df93e713cfb24af golangci-lint-2.10.1-freebsd-amd64.tar.gz 1cbd0c7ade3fb027d61d38a646ec1b51be5846952b4b04a5330e7f4687f2270c golangci-lint-2.0.2-freebsd-amd64.tar.gz
2ef38eefc4b5cee2febacb75a30579526e5656c16338a921d80e59a8e87d4425 golangci-lint-2.10.1-freebsd-arm64.tar.gz 1e828a597726198b2e35acdbcc5f3aad85244d79846d2d2bdb05241c5a535f9e golangci-lint-2.0.2-freebsd-armv6.tar.gz
8fea6766318b4829e766bbe325f10191d75297dcc44ae35bf374816037878e38 golangci-lint-2.10.1-freebsd-armv6.tar.gz 848b49315dc5cddd0c9ce35e96ab33d584db0ea8fb57bcbf9784f1622bec0269 golangci-lint-2.0.2-freebsd-armv7.tar.gz
30b629870574d6254f3e8804e5a74b34f98e1263c9d55465830d739c88b862ed golangci-lint-2.10.1-freebsd-armv7.tar.gz cabf9a6beab574c7f98581eb237919e580024759e3cdc05c4d516b044dce6770 golangci-lint-2.0.2-illumos-amd64.tar.gz
c0db839f866ce80b1b6c96167aa101cfe50d9c936f42d942a3c1cbdc1801af68 golangci-lint-2.10.1-illumos-amd64.tar.gz 2fde80d15ed6527791f106d606120620e913c3a663c90a8596861d0a4461169e golangci-lint-2.0.2-linux-386.deb
280eb56636e9175f671cd7b755d7d67f628ae2ed00a164d1e443c43c112034e5 golangci-lint-2.10.1-linux-386.deb 804bc6e350a8c613aaa0a33d8d45414a80157b0ba1b2c2335ac859f85ad98ebd golangci-lint-2.0.2-linux-386.rpm
065a7d99da61dc7dfbfef2e2d7053dd3fa6672598f2747117aa4bb5f45e7df7f golangci-lint-2.10.1-linux-386.rpm e64beb72fecf581e57d88ae3adb1c9d4bf022694b6bd92e3c8e460910bbdc37d golangci-lint-2.0.2-linux-386.tar.gz
a55918c03bb413b2662287653ab2ae2fef4e37428b247dad6348724adde9d770 golangci-lint-2.10.1-linux-386.tar.gz 9c55aed174d7a52bb1d4006b36e7edee9023631f6b814a80cb39c9860d6f75c3 golangci-lint-2.0.2-linux-amd64.deb
8aa9b3aa14f39745eeb7fc7ff50bcac683e785397d1e4bc9afd2184b12c4ce86 golangci-lint-2.10.1-linux-amd64.deb c55a2ef741a687b4c679696931f7fd4a467babd64c9457cf17bb9632fd1cecd1 golangci-lint-2.0.2-linux-amd64.rpm
62a111688e9e305032334a2cbc84f4d971b64bb3bffc99d3f80081d57fb25e32 golangci-lint-2.10.1-linux-amd64.rpm 89cc8a7810dc63b9a37900da03e37c3601caf46d42265d774e0f1a5d883d53e2 golangci-lint-2.0.2-linux-amd64.tar.gz
dfa775874cf0561b404a02a8f4481fc69b28091da95aa697259820d429b09c99 golangci-lint-2.10.1-linux-amd64.tar.gz a3e78583c4e7ea1b63e82559f126bb3a5b12788676f158526752d53e67824b99 golangci-lint-2.0.2-linux-arm64.deb
b3f36937e8ea1660739dc0f5c892ea59c9c21ed4e75a91a25957c561f7f79a55 golangci-lint-2.10.1-linux-arm64.deb bd5dd52b5c9f18aa7a2904eda9a9f91c628e98623fe70b7afcbb847e2de84422 golangci-lint-2.0.2-linux-arm64.rpm
36d50314d53683b1f1a2a6cedfb5a9468451b481c64ab9e97a8e843ea088074d golangci-lint-2.10.1-linux-arm64.rpm 789d5b91219ac68c2336f77d41cd7e33a910420594780f455893f8453d09595b golangci-lint-2.0.2-linux-arm64.tar.gz
6652b42ae02915eb2f9cb2a2e0cac99514c8eded8388d88ae3e06e1a52c00de8 golangci-lint-2.10.1-linux-arm64.tar.gz 534cd4c464a66178714ed68152c1ed7aa73e5700bf409e4ed1a8363adf96afca golangci-lint-2.0.2-linux-armv6.deb
a32d8d318e803496812dd3461f250e52ccc7f53c47b95ce404a9cf55778ceb6a golangci-lint-2.10.1-linux-armv6.deb cf7d02905a5fc80b96c9a64621693b4cc7337b1ce29986c19fd72608dafe66c5 golangci-lint-2.0.2-linux-armv6.rpm
41d065f4c8ea165a1531abea644988ee2e973e4f0b49f9725ed3b979dac45112 golangci-lint-2.10.1-linux-armv6.rpm a0d81cb527d8fe878377f2356b5773e219b0b91832a6b59e7b9bcf9a90fe0b0e golangci-lint-2.0.2-linux-armv6.tar.gz
59159a4df03aabbde69d15c7b7b3df143363cbb41f4bd4b200caffb8e34fb734 golangci-lint-2.10.1-linux-armv6.tar.gz dedd5be7fff8cba8fe15b658a59347ea90d7d02a9fff87f09c7687e6da05a8b6 golangci-lint-2.0.2-linux-armv7.deb
b2e8ec0e050a1e2251dfe1561434999d202f5a3f9fa47ce94378b0fd1662ea5a golangci-lint-2.10.1-linux-armv7.deb 85521b6f3ad2f5a2bc9bfe14b9b08623f764964048f75ed6dfcfaf8eb7d57cc1 golangci-lint-2.0.2-linux-armv7.rpm
28c9331429a497da27e9c77846063bd0e8275e878ffedb4eb9e9f21d24771cc0 golangci-lint-2.10.1-linux-armv7.rpm 96471046c7780dda4ea680f65e92c2ef56ff58d40bcffaf6cfe9d6d48e3c27aa golangci-lint-2.0.2-linux-armv7.tar.gz
818f33e95b273e3769284b25563b51ef6a294e9e25acf140fda5830c075a1a59 golangci-lint-2.10.1-linux-armv7.tar.gz 815d914a7738e4362466b2d11004e8618b696b49e8ace13df2c2b25f28fb1e17 golangci-lint-2.0.2-linux-loong64.deb
6b6b85ed4b7c27f51097dd681523000409dde835e86e6e314e87be4bb013e2ab golangci-lint-2.10.1-linux-loong64.deb f16381e3d8a0f011b95e086d83d620248432b915d01f4beab4d29cfe4dc388b0 golangci-lint-2.0.2-linux-loong64.rpm
94050a0cf06169e2ae44afb307dcaafa7d7c3b38c0c23b5652cf9cb60f0c337f golangci-lint-2.10.1-linux-loong64.rpm 1bd8d7714f9c92db6a0f23bae89f39c85ba047bec8eeb42b8748d30ae3228d18 golangci-lint-2.0.2-linux-loong64.tar.gz
25820300fccb8c961c1cdcb1f77928040c079e04c43a3a5ceb34b1cb4a1c5c8d golangci-lint-2.10.1-linux-loong64.tar.gz ea6e9d4aabb526aa298e47e8b026d8893d918c5eb919ba0ab403e315def74cc5 golangci-lint-2.0.2-linux-mips64.deb
98bf39d10139fdcaa37f94950e9bbb8888660ae468847ae0bf1cb5bf67c1f68b golangci-lint-2.10.1-linux-mips64.deb 519d8d53af83fdc9c25cc3fba8b663331ac22ef68131d4b0084cb6f425b6f79a golangci-lint-2.0.2-linux-mips64.rpm
df3ce5f03808dcceaa8b683d1d06e95c885f09b59dc8e15deb840fbe2b3e3299 golangci-lint-2.10.1-linux-mips64.rpm 80d655a0a1ac1b19dcef4b58fa2a7dadb646cc50ad08d460b5c53cdb421165e4 golangci-lint-2.0.2-linux-mips64.tar.gz
972508dda523067e6e6a1c8e6609d63bc7c4153819c11b947d439235cf17bac2 golangci-lint-2.10.1-linux-mips64.tar.gz aa0e75384bb482c865d4dfc95d23ceb25666bf20461b67a832f0eea6670312ec golangci-lint-2.0.2-linux-mips64le.deb
1d37f2919e183b5bf8b1777ed8c4b163d3b491d0158355a7999d647655cbbeb6 golangci-lint-2.10.1-linux-mips64le.deb f2a8b500fb69bdea1b01df6267aaa5218fa4a58aeb781c1a20d0d802fe465a52 golangci-lint-2.0.2-linux-mips64le.rpm
e341d031002cd09a416329ed40f674231051a38544b8f94deb2d1708ce1f4a6f golangci-lint-2.10.1-linux-mips64le.rpm e66a0c0c9a275f02d27a7caa9576112622306f001d73dfc082cf1ae446fc1242 golangci-lint-2.0.2-linux-mips64le.tar.gz
393560122b9cb5538df0c357d30eb27b6ee563533fbb9b138c8db4fd264002af golangci-lint-2.10.1-linux-mips64le.tar.gz e85ad51aac6428be2d8a37000d053697371a538a5bcbc1644caa7c5e77f6d0af golangci-lint-2.0.2-linux-ppc64le.deb
21ca46b6a96442e8957677a3ca059c6b93674a68a01b1c71f4e5df0ea2e96d19 golangci-lint-2.10.1-linux-ppc64le.deb 906798365eac1944af2a9b9a303e6fd49ec9043307bc681b7a96277f7f8beea5 golangci-lint-2.0.2-linux-ppc64le.rpm
57fe0cbca0a9bbdf1547c5e8aa7d278e6896b438d72a541bae6bc62c38b43d1e golangci-lint-2.10.1-linux-ppc64le.rpm f7f1a271b0af274d6c9ce000f5dc6e1fb194350c67bcc62494f96f791882ba92 golangci-lint-2.0.2-linux-ppc64le.tar.gz
e2883db9fa51584e5e203c64456f29993550a7faadc84e3faccdb48f0669992e golangci-lint-2.10.1-linux-ppc64le.tar.gz eea8bf643a42bf05de9780530db22923e5ab0d588f0e173594dc6518f2a25d2a golangci-lint-2.0.2-linux-riscv64.deb
aa6da0e98ab0ba3bb7582e112174c349907d5edfeff90a551dca3c6eecf92fc0 golangci-lint-2.10.1-linux-riscv64.deb 4ff40f9fe2954400836e2a011ba4744d00ffab5068a51368552dfce6aba3b81b golangci-lint-2.0.2-linux-riscv64.rpm
3c68d76cd884a7aad206223a980b9c20bb9ea74b560fa27ed02baf2389189234 golangci-lint-2.10.1-linux-riscv64.rpm 531d8f225866674977d630afbf0533eb02f9bec607fb13895f7a2cd7b2e0a648 golangci-lint-2.0.2-linux-riscv64.tar.gz
3bca11bfac4197205639cbd4676a5415054e629ac6c12ea10fcbe33ef852d9c3 golangci-lint-2.10.1-linux-riscv64.tar.gz 6f827647046c603f40d97ea5aadc6f48cd0bb5d19f7a3d56500c3b833d2a0342 golangci-lint-2.0.2-linux-s390x.deb
0c6aed2ce49db2586adbac72c80d871f06feb1caf4c0763a5ca98fec809a8f0b golangci-lint-2.10.1-linux-s390x.deb 387a090e9576d19ca86aac738172e58e07c19f2784a13bb387f4f0d75fb9c8d3 golangci-lint-2.0.2-linux-s390x.rpm
16c285adfe1061d69dd8e503be69f87c7202857c6f4add74ac02e3571158fbec golangci-lint-2.10.1-linux-s390x.rpm 57de1fb7722a9feb2d11ed0a007a93959d05b9db5929a392abc222e30012467e golangci-lint-2.0.2-linux-s390x.tar.gz
21011ad368eb04f024201b832095c6b5f96d0888de194cca5bfe4d9307d6364b golangci-lint-2.10.1-linux-s390x.tar.gz ed95e0492ea86bf79eb661f0334474b2a4255093685ff587eccd797c5a54db7e golangci-lint-2.0.2-netbsd-386.tar.gz
7b5191e77a70485918712e31ed55159956323e4911bab1b67569c9d86e1b75eb golangci-lint-2.10.1-netbsd-386.tar.gz eab81d729778166415d349a80e568b2f2b3a781745a9be3212a92abb1e732daf golangci-lint-2.0.2-netbsd-amd64.tar.gz
07801fd38d293ebad10826f8285525a39ea91ce5ddad77d05bfa90bda9c884a9 golangci-lint-2.10.1-netbsd-amd64.tar.gz d20add73f7c2de2c3b01ed4fd7b63ffcf0a6597d5ea228d1699e92339a3cd047 golangci-lint-2.0.2-netbsd-arm64.tar.gz
7e7219d71c1bf33b98c328c93dc0560706dd896a1c43c44696e5222fc9d7446e golangci-lint-2.10.1-netbsd-arm64.tar.gz 4e4f44e6057879cd62424ff1800a767d25a595c0e91d6d48809eea9186b4c739 golangci-lint-2.0.2-netbsd-armv6.tar.gz
92fbc90b9eec0e572269b0f5492a2895c426b086a68372fde49b7e4d4020863e golangci-lint-2.10.1-netbsd-armv6.tar.gz 51ec17b16d8743ae4098a0171f04f0ed4d64561e3051b982778b0e6c306a1b03 golangci-lint-2.0.2-netbsd-armv7.tar.gz
f67b3ae1f47caeefa507a4ebb0c8336958a19011fe48766443212030f75d004b golangci-lint-2.10.1-netbsd-armv7.tar.gz 5482cf27b93fae1765c70ee2a95d4074d038e9dee61bdd61d017ce8893d3a4a8 golangci-lint-2.0.2-source.tar.gz
a40bc091c10cea84eaee1a90b84b65f5e8652113b0a600bb099e4e4d9d7caddb golangci-lint-2.10.1-windows-386.zip a35d8fdf3e14079a10880dbbb7586b46faec89be96f086b244b3e565aac80313 golangci-lint-2.0.2-windows-386.zip
c60c87695e79db8e320f0e5be885059859de52bb5ee5f11be5577828570bc2a3 golangci-lint-2.10.1-windows-amd64.zip fe4b946cc01366b989001215687003a9c4a7098589921f75e6228d6d8cffc15c golangci-lint-2.0.2-windows-amd64.zip
636ab790c8dcea8034aa34aba6031ca3893d68f7eda000460ab534341fadbab1 golangci-lint-2.10.1-windows-arm64.zip 646bd9250ef8c771d85cd22fe8e6f2397ae39599179755e3bbfa9ef97ad44090 golangci-lint-2.0.2-windows-arm64.zip
ce1dc0bad6f8a61d64e6b3779eeb773479c175125d6f686b0e67ef9c8432d16e golangci-lint-2.0.2-windows-armv6.zip
92684a48faabe792b11ac27ca8b25551eff940b0a1e84ad7244e98b4994962db golangci-lint-2.0.2-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!
# #

View file

@ -31,9 +31,6 @@ Available commands are:
install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
test [ -coverage ] [ packages... ] -- runs the tests test [ -coverage ] [ packages... ] -- runs the tests
keeper [ -dlgo ]
keeper-archive [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ]
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts
importkeys -- imports signing keys from env importkeys -- imports signing keys from env
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
@ -60,7 +57,6 @@ import (
"time" "time"
"github.com/cespare/cp" "github.com/cespare/cp"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto/signify" "github.com/ethereum/go-ethereum/crypto/signify"
"github.com/ethereum/go-ethereum/internal/build" "github.com/ethereum/go-ethereum/internal/build"
"github.com/ethereum/go-ethereum/internal/download" "github.com/ethereum/go-ethereum/internal/download"
@ -68,11 +64,6 @@ import (
) )
var ( var (
goModules = []string{
".",
"./cmd/keeper",
}
// Files that end up in the geth*.zip archive. // Files that end up in the geth*.zip archive.
gethArchiveFiles = []string{ gethArchiveFiles = []string{
"COPYING", "COPYING",
@ -89,42 +80,6 @@ var (
executablePath("clef"), executablePath("clef"),
} }
// Keeper build targets with their configurations
keeperTargets = []struct {
Name string
GOOS string
GOARCH string
CC string
Tags string
Env map[string]string
}{
{
Name: "ziren",
GOOS: "linux",
GOARCH: "mipsle",
// enable when cgo works
// CC: "mipsel-linux-gnu-gcc",
Tags: "ziren",
Env: map[string]string{"GOMIPS": "softfloat", "CGO_ENABLED": "0"},
},
{
Name: "wasm-js",
GOOS: "js",
GOARCH: "wasm",
Tags: "example",
},
{
Name: "wasm-wasi",
GOOS: "wasip1",
GOARCH: "wasm",
Tags: "example",
},
{
Name: "example",
Tags: "example",
},
}
// A debian package is created for all executables listed here. // A debian package is created for all executables listed here.
debExecutables = []debExecutable{ debExecutables = []debExecutable{
{ {
@ -168,6 +123,7 @@ var (
"focal", // 20.04, EOL: 04/2030 "focal", // 20.04, EOL: 04/2030
"jammy", // 22.04, EOL: 04/2032 "jammy", // 22.04, EOL: 04/2032
"noble", // 24.04, EOL: 04/2034 "noble", // 24.04, EOL: 04/2034
"oracular", // 24.10, EOL: 07/2025
} }
// This is where the tests should be unpacked. // This is where the tests should be unpacked.
@ -186,7 +142,7 @@ func executablePath(name string) string {
func main() { func main() {
log.SetFlags(log.Lshortfile) log.SetFlags(log.Lshortfile)
if !common.FileExist(filepath.Join("build", "ci.go")) { if !build.FileExist(filepath.Join("build", "ci.go")) {
log.Fatal("this script must be run from the root of the repository") log.Fatal("this script must be run from the root of the repository")
} }
if len(os.Args) < 2 { if len(os.Args) < 2 {
@ -215,10 +171,6 @@ func main() {
doPurge(os.Args[2:]) doPurge(os.Args[2:])
case "sanitycheck": case "sanitycheck":
doSanityCheck() doSanityCheck()
case "keeper":
doInstallKeeper(os.Args[2:])
case "keeper-archive":
doKeeperArchive(os.Args[2:])
default: default:
log.Fatal("unknown command ", os.Args[1]) log.Fatal("unknown command ", os.Args[1])
} }
@ -253,6 +205,9 @@ func doInstall(cmdline []string) {
// Configure the build. // Configure the build.
gobuild := tc.Go("build", buildFlags(env, *staticlink, buildTags)...) gobuild := tc.Go("build", buildFlags(env, *staticlink, buildTags)...)
// We use -trimpath to avoid leaking local paths into the built executables.
gobuild.Args = append(gobuild.Args, "-trimpath")
// Show packages during build. // Show packages during build.
gobuild.Args = append(gobuild.Args, "-v") gobuild.Args = append(gobuild.Args, "-v")
@ -260,7 +215,7 @@ func doInstall(cmdline []string) {
// Default: collect all 'main' packages in cmd/ and build those. // Default: collect all 'main' packages in cmd/ and build those.
packages := flag.Args() packages := flag.Args()
if len(packages) == 0 { if len(packages) == 0 {
packages = build.FindMainPackages(&tc, "./cmd/...") packages = build.FindMainPackages("./cmd")
} }
// Do the build! // Do the build!
@ -272,43 +227,6 @@ func doInstall(cmdline []string) {
} }
} }
// doInstallKeeper builds keeper binaries for all supported targets.
func doInstallKeeper(cmdline []string) {
var dlgo = flag.Bool("dlgo", false, "Download Go and build with it")
flag.CommandLine.Parse(cmdline)
env := build.Env()
// Configure the toolchain.
tc := build.GoToolchain{}
if *dlgo {
csdb := download.MustLoadChecksums("build/checksums.txt")
tc.Root = build.DownloadGo(csdb)
}
for _, target := range keeperTargets {
log.Printf("Building keeper-%s", target.Name)
// Configure the build.
tc.GOARCH = target.GOARCH
tc.GOOS = target.GOOS
tc.CC = target.CC
gobuild := tc.Go("build", buildFlags(env, true, []string{target.Tags})...)
gobuild.Dir = "./cmd/keeper"
gobuild.Args = append(gobuild.Args, "-v")
for key, value := range target.Env {
gobuild.Env = append(gobuild.Env, key+"="+value)
}
outputName := fmt.Sprintf("keeper-%s", target.Name)
args := slices.Clone(gobuild.Args)
args = append(args, "-o", executablePath(outputName))
args = append(args, ".")
build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env})
}
}
// 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
@ -341,18 +259,12 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (
} }
ld = append(ld, "-extldflags", "'"+strings.Join(extld, " ")+"'") ld = append(ld, "-extldflags", "'"+strings.Join(extld, " ")+"'")
} }
// TODO(gballet): revisit after the input api has been defined
if runtime.GOARCH == "wasm" {
ld = append(ld, "-gcflags=all=-d=softfloat")
}
if len(ld) > 0 { if len(ld) > 0 {
flags = append(flags, "-ldflags", strings.Join(ld, " ")) flags = append(flags, "-ldflags", strings.Join(ld, " "))
} }
if len(buildTags) > 0 { if len(buildTags) > 0 {
flags = append(flags, "-tags", strings.Join(buildTags, ",")) flags = append(flags, "-tags", strings.Join(buildTags, ","))
} }
// We use -trimpath to avoid leaking local paths into the built executables.
flags = append(flags, "-trimpath")
return flags return flags
} }
@ -370,24 +282,18 @@ func doTest(cmdline []string) {
race = flag.Bool("race", false, "Execute the race detector") race = flag.Bool("race", false, "Execute the race detector")
short = flag.Bool("short", false, "Pass the 'short'-flag to go test") short = flag.Bool("short", false, "Pass the 'short'-flag to go test")
cachedir = flag.String("cachedir", "./build/cache", "directory for caching downloads") cachedir = flag.String("cachedir", "./build/cache", "directory for caching downloads")
threads = flag.Int("p", 1, "Number of CPU threads to use for testing")
) )
flag.CommandLine.Parse(cmdline) flag.CommandLine.Parse(cmdline)
// Load checksums file (needed for both spec tests and dlgo)
csdb := download.MustLoadChecksums("build/checksums.txt")
// Get test fixtures. // Get test fixtures.
if !*short { csdb := download.MustLoadChecksums("build/checksums.txt")
downloadSpecTestFixtures(csdb, *cachedir) downloadSpecTestFixtures(csdb, *cachedir)
}
// Configure the toolchain. // Configure the toolchain.
tc := build.GoToolchain{GOARCH: *arch, CC: *cc} tc := build.GoToolchain{GOARCH: *arch, CC: *cc}
if *dlgo { if *dlgo {
tc.Root = build.DownloadGo(csdb) tc.Root = build.DownloadGo(csdb)
} }
gotest := tc.Go("test") gotest := tc.Go("test")
// CI needs a bit more time for the statetests (default 45m). // CI needs a bit more time for the statetests (default 45m).
@ -401,7 +307,7 @@ func doTest(cmdline []string) {
// Test a single package at a time. CI builders are slow // Test a single package at a time. CI builders are slow
// and some tests run into timeouts under load. // and some tests run into timeouts under load.
gotest.Args = append(gotest.Args, "-p", fmt.Sprintf("%d", *threads)) gotest.Args = append(gotest.Args, "-p", "1")
if *coverage { if *coverage {
gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover") gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover")
} }
@ -415,26 +321,18 @@ func doTest(cmdline []string) {
gotest.Args = append(gotest.Args, "-short") gotest.Args = append(gotest.Args, "-short")
} }
packages := flag.CommandLine.Args() packages := []string{"./..."}
if len(packages) > 0 { if len(flag.CommandLine.Args()) > 0 {
gotest.Args = append(gotest.Args, packages...) packages = flag.CommandLine.Args()
build.MustRun(gotest)
return
}
// No packages specified, run all tests for all modules.
gotest.Args = append(gotest.Args, "./...")
for _, mod := range goModules {
test := *gotest
test.Dir = mod
build.MustRun(&test)
} }
gotest.Args = append(gotest.Args, packages...)
build.MustRun(gotest)
} }
// downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures. // downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures.
func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string { func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string {
ext := ".tar.gz" ext := ".tar.gz"
base := "fixtures_develop" base := "fixtures_fusaka-devnet-3"
archivePath := filepath.Join(cachedir, base+ext) archivePath := filepath.Join(cachedir, base+ext)
if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil {
log.Fatal(err) log.Fatal(err)
@ -445,6 +343,10 @@ func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string
return filepath.Join(cachedir, base) return filepath.Join(cachedir, base)
} }
// doCheckTidy assets that the Go modules files are tidied already.
func doCheckTidy() {
}
// doCheckGenerate ensures that re-generating generated files does not cause // doCheckGenerate ensures that re-generating generated files does not cause
// any mutations in the source file tree. // any mutations in the source file tree.
func doCheckGenerate() { func doCheckGenerate() {
@ -452,51 +354,40 @@ func doCheckGenerate() {
cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.") cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.")
tc = new(build.GoToolchain) tc = new(build.GoToolchain)
) )
// Compute the origin hashes of all the files
var hashes map[string][32]byte
var err error
hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"})
if err != nil {
log.Fatal("Error computing hashes", "err", err)
}
// Run any go generate steps we might be missing // Run any go generate steps we might be missing
var ( var (
protocPath = downloadProtoc(*cachedir) protocPath = downloadProtoc(*cachedir)
protocGenGoPath = downloadProtocGenGo(*cachedir) protocGenGoPath = downloadProtocGenGo(*cachedir)
) )
c := tc.Go("generate", "./...")
pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")} 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)
excludes := []string{"tests/testdata", "build/cache", ".git"} // Check if generate file hashes have changed
for i := range excludes { generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"})
excludes[i] = filepath.FromSlash(excludes[i]) if err != nil {
log.Fatalf("Error re-computing hashes: %v", err)
} }
updates := build.DiffHashes(hashes, generated)
for _, mod := range goModules { for _, file := range updates {
// Compute the origin hashes of all the files log.Printf("File changed: %s", file)
hashes, err := build.HashFolder(mod, excludes) }
if err != nil { if len(updates) != 0 {
log.Fatal("Error computing hashes", "err", err) log.Fatal("One or more generated files were updated by running 'go generate ./...'")
}
c := tc.Go("generate", "./...")
c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator)))
c.Dir = mod
build.MustRun(c)
// Check if generate file hashes have changed
generated, err := build.HashFolder(mod, excludes)
if err != nil {
log.Fatalf("Error re-computing hashes: %v", err)
}
updates := build.DiffHashes(hashes, generated)
for _, file := range updates {
log.Printf("File changed: %s", file)
}
if len(updates) != 0 {
log.Fatal("One or more generated files were updated by running 'go generate ./...'")
}
} }
fmt.Println("No stale files detected.") fmt.Println("No stale files detected.")
// Run go mod tidy check. // Run go mod tidy check.
for _, mod := range goModules { build.MustRun(tc.Go("mod", "tidy", "-diff"))
tidy := tc.Go("mod", "tidy", "-diff")
tidy.Dir = mod
build.MustRun(tidy)
}
fmt.Println("No untidy module files detected.") fmt.Println("No untidy module files detected.")
} }
@ -536,30 +427,14 @@ func doLint(cmdline []string) {
cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.") cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.")
) )
flag.CommandLine.Parse(cmdline) flag.CommandLine.Parse(cmdline)
packages := []string{"./..."}
if len(flag.CommandLine.Args()) > 0 {
packages = flag.CommandLine.Args()
}
linter := downloadLinter(*cachedir) linter := downloadLinter(*cachedir)
linter, err := filepath.Abs(linter) lflags := []string{"run", "--config", ".golangci.yml"}
if err != nil { build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
log.Fatal(err)
}
config, err := filepath.Abs(".golangci.yml")
if err != nil {
log.Fatal(err)
}
lflags := []string{"run", "--config", config}
packages := flag.CommandLine.Args()
if len(packages) > 0 {
build.MustRunCommandWithOutput(linter, append(lflags, packages...)...)
} else {
// Run for all modules in workspace.
for _, mod := range goModules {
args := append(lflags, "./...")
lintcmd := exec.Command(linter, args...)
lintcmd.Dir = mod
build.MustRunWithOutput(lintcmd)
}
}
fmt.Println("You have achieved perfection.") fmt.Println("You have achieved perfection.")
} }
@ -715,32 +590,6 @@ func doArchive(cmdline []string) {
} }
} }
func doKeeperArchive(cmdline []string) {
var (
signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`)
signify = flag.String("signify", "", `Environment variable holding the signify key (e.g. LINUX_SIGNIFY_KEY)`)
upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`)
)
flag.CommandLine.Parse(cmdline)
var (
env = build.Env()
vsn = version.Archive(env.Commit)
keeper = "keeper-" + vsn + ".tar.gz"
)
maybeSkipArchive(env)
files := []string{"COPYING"}
for _, target := range keeperTargets {
files = append(files, executablePath(fmt.Sprintf("keeper-%s", target.Name)))
}
if err := build.WriteArchive(keeper, files); err != nil {
log.Fatal(err)
}
if err := archiveUpload(keeper, *upload, *signer, *signify); err != nil {
log.Fatal(err)
}
}
func archiveBasename(arch string, archiveVersion string) string { func archiveBasename(arch string, archiveVersion string) string {
platform := runtime.GOOS + "-" + arch platform := runtime.GOOS + "-" + arch
if arch == "arm" { if arch == "arm" {
@ -1013,7 +862,7 @@ func ppaUpload(workdir, ppa, sshUser string, files []string) {
var idfile string var idfile string
if sshkey := getenvBase64("PPA_SSH_KEY"); len(sshkey) > 0 { if sshkey := getenvBase64("PPA_SSH_KEY"); len(sshkey) > 0 {
idfile = filepath.Join(workdir, "sshkey") idfile = filepath.Join(workdir, "sshkey")
if !common.FileExist(idfile) { if !build.FileExist(idfile) {
os.WriteFile(idfile, sshkey, 0600) os.WriteFile(idfile, sshkey, 0600)
} }
} }

View file

@ -1,4 +1,4 @@
// Copyright 2025 The go-ethereum Authors // Copyright 2019 The go-ethereum Authors
// This file is part of the go-ethereum library. // This file is part of the go-ethereum library.
// //
// The go-ethereum library is free software: you can redistribute it and/or modify // The go-ethereum library is free software: you can redistribute it and/or modify
@ -14,17 +14,14 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package rawdb //go:build tools
// +build tools
package tools
import ( import (
"github.com/ethereum/go-ethereum/common" // Tool imports for go:generate.
"github.com/ethereum/go-ethereum/ethdb" _ "github.com/fjl/gencodec"
_ "golang.org/x/tools/cmd/stringer"
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
) )
func ReadVerkleTransitionState(db ethdb.KeyValueReader, hash common.Hash) ([]byte, error) {
return db.Get(transitionStateKey(hash))
}
func WriteVerkleTransitionState(db ethdb.KeyValueWriter, hash common.Hash, state []byte) error {
return db.Put(transitionStateKey(hash), state)
}

32
circle.yml Normal file
View file

@ -0,0 +1,32 @@
machine:
services:
- docker
dependencies:
cache_directories:
- "~/.ethash" # Cache the ethash DAG generated by hive for consecutive builds
- "~/.docker" # Cache all docker images manually to avoid lengthy rebuilds
override:
# Restore all previously cached docker images
- mkdir -p ~/.docker
- for img in `ls ~/.docker`; do docker load -i ~/.docker/$img; done
# Pull in and hive, restore cached ethash DAGs and do a dry run
- go get -u github.com/karalabe/hive
- (cd ~/.go_workspace/src/github.com/karalabe/hive && mkdir -p workspace/ethash/ ~/.ethash)
- (cd ~/.go_workspace/src/github.com/karalabe/hive && cp -r ~/.ethash/. workspace/ethash/)
- (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=NONE --test=. --sim=. --loglevel=6)
# Cache all the docker images and the ethash DAGs
- for img in `docker images | grep -v "^<none>" | tail -n +2 | awk '{print $1}'`; do docker save $img > ~/.docker/`echo $img | tr '/' ':'`.tar; done
- cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/ethash/. ~/.ethash
test:
override:
# Build Geth and move into a known folder
- make geth
- cp ./build/bin/geth $HOME/geth
# Run hive and move all generated logs into the public artifacts folder
- (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/geth --test=. --sim=.)
- cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/logs/* $CIRCLE_ARTIFACTS

View file

@ -121,7 +121,7 @@ with our test chain. The chain files are located in `./cmd/devp2p/internal/ethte
--nat=none \ --nat=none \
--networkid 3503995874084926 \ --networkid 3503995874084926 \
--verbosity 5 \ --verbosity 5 \
--authrpc.jwtsecret jwt.secret --authrpc.jwtsecret 0x7365637265747365637265747365637265747365637265747365637265747365
Note that the tests also require access to the engine API. Note that the tests also require access to the engine API.
The test suite can now be executed using the devp2p tool. The test suite can now be executed using the devp2p tool.
@ -130,7 +130,7 @@ The test suite can now be executed using the devp2p tool.
--chain internal/ethtest/testdata \ --chain internal/ethtest/testdata \
--node enode://.... \ --node enode://.... \
--engineapi http://127.0.0.1:8551 \ --engineapi http://127.0.0.1:8551 \
--jwtsecret $(cat jwt.secret) --jwtsecret 0x7365637265747365637265747365637265747365637265747365637265747365
Repeat the above process (re-initialising the node) in order to run the Eth Protocol test suite again. Repeat the above process (re-initialising the node) in order to run the Eth Protocol test suite again.

View file

@ -155,7 +155,7 @@ func (c *Conn) ReadEth() (any, error) {
var msg any var msg any
switch int(code) { switch int(code) {
case eth.StatusMsg: case eth.StatusMsg:
msg = new(eth.StatusPacket) msg = new(eth.StatusPacket69)
case eth.GetBlockHeadersMsg: case eth.GetBlockHeadersMsg:
msg = new(eth.GetBlockHeadersPacket) msg = new(eth.GetBlockHeadersPacket)
case eth.BlockHeadersMsg: case eth.BlockHeadersMsg:
@ -164,6 +164,10 @@ func (c *Conn) ReadEth() (any, error) {
msg = new(eth.GetBlockBodiesPacket) msg = new(eth.GetBlockBodiesPacket)
case eth.BlockBodiesMsg: case eth.BlockBodiesMsg:
msg = new(eth.BlockBodiesPacket) msg = new(eth.BlockBodiesPacket)
case eth.NewBlockMsg:
msg = new(eth.NewBlockPacket)
case eth.NewBlockHashesMsg:
msg = new(eth.NewBlockHashesPacket)
case eth.TransactionsMsg: case eth.TransactionsMsg:
msg = new(eth.TransactionsPacket) msg = new(eth.TransactionsPacket)
case eth.NewPooledTransactionHashesMsg: case eth.NewPooledTransactionHashesMsg:
@ -225,7 +229,7 @@ func (c *Conn) ReadSnap() (any, error) {
} }
// dialAndPeer creates a peer connection and runs the handshake. // dialAndPeer creates a peer connection and runs the handshake.
func (s *Suite) dialAndPeer(status *eth.StatusPacket) (*Conn, error) { func (s *Suite) dialAndPeer(status *eth.StatusPacket69) (*Conn, error) {
c, err := s.dial() c, err := s.dial()
if err != nil { if err != nil {
return nil, err return nil, err
@ -238,7 +242,7 @@ func (s *Suite) dialAndPeer(status *eth.StatusPacket) (*Conn, error) {
// peer performs both the protocol handshake and the status message // peer performs both the protocol handshake and the status message
// exchange with the node in order to peer with it. // exchange with the node in order to peer with it.
func (c *Conn) peer(chain *Chain, status *eth.StatusPacket) error { func (c *Conn) peer(chain *Chain, status *eth.StatusPacket69) error {
if err := c.handshake(); err != nil { if err := c.handshake(); err != nil {
return fmt.Errorf("handshake failed: %v", err) return fmt.Errorf("handshake failed: %v", err)
} }
@ -311,7 +315,7 @@ func (c *Conn) negotiateEthProtocol(caps []p2p.Cap) {
} }
// statusExchange performs a `Status` message exchange with the given node. // statusExchange performs a `Status` message exchange with the given node.
func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket) error { func (c *Conn) statusExchange(chain *Chain, status *eth.StatusPacket69) error {
loop: loop:
for { for {
code, data, err := c.Read() code, data, err := c.Read()
@ -320,7 +324,7 @@ loop:
} }
switch code { switch code {
case eth.StatusMsg + protoOffset(ethProto): case eth.StatusMsg + protoOffset(ethProto):
msg := new(eth.StatusPacket) msg := new(eth.StatusPacket69)
if err := rlp.DecodeBytes(data, &msg); err != nil { if err := rlp.DecodeBytes(data, &msg); err != nil {
return fmt.Errorf("error decoding status packet: %w", err) return fmt.Errorf("error decoding status packet: %w", err)
} }
@ -359,7 +363,7 @@ loop:
} }
if status == nil { if status == nil {
// default status message // default status message
status = &eth.StatusPacket{ status = &eth.StatusPacket69{
ProtocolVersion: uint32(c.negotiatedProtoVersion), ProtocolVersion: uint32(c.negotiatedProtoVersion),
NetworkID: chain.config.ChainID.Uint64(), NetworkID: chain.config.ChainID.Uint64(),
Genesis: chain.blocks[0].Hash(), Genesis: chain.blocks[0].Hash(),

View file

@ -1,10 +1,9 @@
#!/bin/sh #!/bin/sh
hivechain generate \ hivechain generate \
--pos \
--fork-interval 6 \ --fork-interval 6 \
--tx-interval 1 \ --tx-interval 1 \
--length 600 \ --length 500 \
--outdir testdata \ --outdir testdata \
--lastfork prague \ --lastfork cancun \
--outputs accounts,genesis,chain,headstate,txinfo,headblock,headfcu,newpayload,forkenv --outputs accounts,genesis,chain,headstate,txinfo,headblock,headfcu,newpayload,forkenv

View file

@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/eth/protocols/snap"
"github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/internal/utesting"
"github.com/ethereum/go-ethereum/rlp"
"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"
) )
@ -87,9 +86,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) {
root: root, root: root,
startingHash: zero, startingHash: zero,
limitHash: ffHash, limitHash: ffHash,
expAccounts: 67, expAccounts: 86,
expFirst: firstKey, expFirst: firstKey,
expLast: common.HexToHash("0x622e662246601dd04f996289ce8b85e86db7bb15bb17f86487ec9d543ddb6f9a"), expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"),
desc: "In this test, we request the entire state range, but limit the response to 4000 bytes.", desc: "In this test, we request the entire state range, but limit the response to 4000 bytes.",
}, },
{ {
@ -97,9 +96,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) {
root: root, root: root,
startingHash: zero, startingHash: zero,
limitHash: ffHash, limitHash: ffHash,
expAccounts: 49, expAccounts: 65,
expFirst: firstKey, expFirst: firstKey,
expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"), expLast: common.HexToHash("0x2e6fe1362b3e388184fd7bf08e99e74170b26361624ffd1c5f646da7067b58b6"),
desc: "In this test, we request the entire state range, but limit the response to 3000 bytes.", desc: "In this test, we request the entire state range, but limit the response to 3000 bytes.",
}, },
{ {
@ -107,9 +106,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) {
root: root, root: root,
startingHash: zero, startingHash: zero,
limitHash: ffHash, limitHash: ffHash,
expAccounts: 34, expAccounts: 44,
expFirst: firstKey, expFirst: firstKey,
expLast: common.HexToHash("0x2ef46ebd2073cecde499c2e8df028ad79a26d57bfaa812c4c6f7eb4c9617b913"), expLast: common.HexToHash("0x1c3f74249a4892081ba0634a819aec9ed25f34c7653f5719b9098487e65ab595"),
desc: "In this test, we request the entire state range, but limit the response to 2000 bytes.", desc: "In this test, we request the entire state range, but limit the response to 2000 bytes.",
}, },
{ {
@ -178,9 +177,9 @@ The server should return the first available account.`,
root: root, root: root,
startingHash: firstKey, startingHash: firstKey,
limitHash: ffHash, limitHash: ffHash,
expAccounts: 67, expAccounts: 86,
expFirst: firstKey, expFirst: firstKey,
expLast: common.HexToHash("0x622e662246601dd04f996289ce8b85e86db7bb15bb17f86487ec9d543ddb6f9a"), expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"),
desc: `In this test, startingHash is exactly the first available account key. desc: `In this test, startingHash is exactly the first available account key.
The server should return the first available account of the state as the first item.`, The server should return the first available account of the state as the first item.`,
}, },
@ -189,9 +188,9 @@ The server should return the first available account of the state as the first i
root: root, root: root,
startingHash: hashAdd(firstKey, 1), startingHash: hashAdd(firstKey, 1),
limitHash: ffHash, limitHash: ffHash,
expAccounts: 67, expAccounts: 86,
expFirst: secondKey, expFirst: secondKey,
expLast: common.HexToHash("0x66192e4c757fba1cdc776e6737008f42d50370d3cd801db3624274283bf7cd63"), expLast: common.HexToHash("0x4615e5f5df5b25349a00ad313c6cd0436b6c08ee5826e33a018661997f85ebaa"),
desc: `In this test, startingHash is after the first available key. desc: `In this test, startingHash is after the first available key.
The server should return the second account of the state as the first item.`, The server should return the second account of the state as the first item.`,
}, },
@ -227,9 +226,9 @@ server to return no data because genesis is older than 127 blocks.`,
root: s.chain.RootAt(int(s.chain.Head().Number().Uint64()) - 127), root: s.chain.RootAt(int(s.chain.Head().Number().Uint64()) - 127),
startingHash: zero, startingHash: zero,
limitHash: ffHash, limitHash: ffHash,
expAccounts: 66, expAccounts: 84,
expFirst: firstKey, expFirst: firstKey,
expLast: common.HexToHash("0x729953a43ed6c913df957172680a17e5735143ad767bda8f58ac84ec62fbec5e"), expLast: common.HexToHash("0x580aa878e2f92d113a12c0a3ce3c21972b03dbe80786858d49a72097e2c491a3"),
desc: `This test requests data at a state root that is 127 blocks old. desc: `This test requests data at a state root that is 127 blocks old.
We expect the server to have this state available.`, We expect the server to have this state available.`,
}, },
@ -658,8 +657,8 @@ The server should reject the request.`,
// It's a bit unfortunate these are hard-coded, but the result depends on // It's a bit unfortunate these are hard-coded, but the result depends on
// a lot of aspects of the state trie and can't be guessed in a simple // a lot of aspects of the state trie and can't be guessed in a simple
// way. So you'll have to update this when the test chain is changed. // way. So you'll have to update this when the test chain is changed.
common.HexToHash("0x5bdc0d6057b35642a16d27223ea5454e5a17a400e28f7328971a5f2a87773b76"), common.HexToHash("0x3e963a69401a70224cbfb8c0cc2249b019041a538675d71ccf80c9328d114e2e"),
common.HexToHash("0x0a76c9812ca90ffed8ee4d191e683f93386b6e50cfe3679c0760d27510aa7fc5"), common.HexToHash("0xd0670d09cdfbf3c6320eb3e92c47c57baa6c226551a2d488c05581091e6b1689"),
empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty,
@ -679,8 +678,8 @@ The server should reject the request.`,
// be updated when the test chain is changed. // be updated when the test chain is changed.
expHashes: []common.Hash{ expHashes: []common.Hash{
empty, empty,
common.HexToHash("0x0a76c9812ca90ffed8ee4d191e683f93386b6e50cfe3679c0760d27510aa7fc5"), common.HexToHash("0xd0670d09cdfbf3c6320eb3e92c47c57baa6c226551a2d488c05581091e6b1689"),
common.HexToHash("0x5bdc0d6057b35642a16d27223ea5454e5a17a400e28f7328971a5f2a87773b76"), common.HexToHash("0x3e963a69401a70224cbfb8c0cc2249b019041a538675d71ccf80c9328d114e2e"),
}, },
}, },
@ -938,14 +937,10 @@ func (s *Suite) snapGetTrieNodes(t *utesting.T, tc *trieNodesTest) error {
} }
// write0 request // write0 request
paths, err := rlp.EncodeToRawList(tc.paths)
if err != nil {
panic(err)
}
req := &snap.GetTrieNodesPacket{ req := &snap.GetTrieNodesPacket{
ID: uint64(rand.Int63()), ID: uint64(rand.Int63()),
Root: tc.root, Root: tc.root,
Paths: paths, Paths: tc.paths,
Bytes: tc.nBytes, Bytes: tc.nBytes,
} }
msg, err := conn.snapRequest(snap.GetTrieNodesMsg, req) msg, err := conn.snapRequest(snap.GetTrieNodesMsg, req)

View file

@ -34,7 +34,6 @@ import (
"github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/internal/utesting"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/rlp"
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
@ -152,11 +151,7 @@ func (s *Suite) TestGetBlockHeaders(t *utesting.T) {
if err != nil { if err != nil {
t.Fatalf("failed to get headers for given request: %v", err) t.Fatalf("failed to get headers for given request: %v", err)
} }
received, err := headers.List.Items() if !headersMatch(expected, headers.BlockHeadersRequest) {
if err != nil {
t.Fatalf("invalid headers received: %v", err)
}
if !headersMatch(expected, received) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers) t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
} }
} }
@ -201,7 +196,6 @@ to check if the node disconnects after receiving multiple invalid requests.`)
func (s *Suite) TestSimultaneousRequests(t *utesting.T) { func (s *Suite) TestSimultaneousRequests(t *utesting.T) {
t.Log(`This test requests blocks headers from the node, performing two requests t.Log(`This test requests blocks headers from the node, performing two requests
concurrently, with different request IDs.`) concurrently, with different request IDs.`)
conn, err := s.dialAndPeer(nil) conn, err := s.dialAndPeer(nil)
if err != nil { if err != nil {
t.Fatalf("peering failed: %v", err) t.Fatalf("peering failed: %v", err)
@ -241,30 +235,37 @@ concurrently, with different request IDs.`)
} }
// Wait for responses. // Wait for responses.
// Note they can arrive in either order. headers1 := new(eth.BlockHeadersPacket)
resp, err := collectHeaderResponses(conn, 2, func(msg *eth.BlockHeadersPacket) uint64 { if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers1); err != nil {
if msg.RequestId != 111 && msg.RequestId != 222 { t.Fatalf("error reading block headers msg: %v", err)
t.Fatalf("response with unknown request ID: %v", msg.RequestId) }
} if got, want := headers1.RequestId, req1.RequestId; got != want {
return msg.RequestId t.Fatalf("unexpected request id in response: got %d, want %d", got, want)
}) }
if err != nil { headers2 := new(eth.BlockHeadersPacket)
t.Fatal(err) if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers2); err != nil {
t.Fatalf("error reading block headers msg: %v", err)
}
if got, want := headers2.RequestId, req2.RequestId; got != want {
t.Fatalf("unexpected request id in response: got %d, want %d", got, want)
} }
// Check if headers match. // Check received headers for accuracy.
if err := s.checkHeadersAgainstChain(req1, resp[111]); err != nil { if expected, err := s.chain.GetHeaders(req1); err != nil {
t.Fatal(err) t.Fatalf("failed to get expected headers for request 1: %v", err)
} else if !headersMatch(expected, headers1.BlockHeadersRequest) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers1)
} }
if err := s.checkHeadersAgainstChain(req2, resp[222]); err != nil { if expected, err := s.chain.GetHeaders(req2); err != nil {
t.Fatal(err) t.Fatalf("failed to get expected headers for request 2: %v", err)
} else if !headersMatch(expected, headers2.BlockHeadersRequest) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers2)
} }
} }
func (s *Suite) TestSameRequestID(t *utesting.T) { func (s *Suite) TestSameRequestID(t *utesting.T) {
t.Log(`This test requests block headers, performing two concurrent requests with the t.Log(`This test requests block headers, performing two concurrent requests with the
same request ID. The node should handle the request by responding to both requests.`) same request ID. The node should handle the request by responding to both requests.`)
conn, err := s.dialAndPeer(nil) conn, err := s.dialAndPeer(nil)
if err != nil { if err != nil {
t.Fatalf("peering failed: %v", err) t.Fatalf("peering failed: %v", err)
@ -288,7 +289,7 @@ same request ID. The node should handle the request by responding to both reques
Origin: eth.HashOrNumber{ Origin: eth.HashOrNumber{
Number: 33, Number: 33,
}, },
Amount: 3, Amount: 2,
}, },
} }
@ -300,61 +301,35 @@ same request ID. The node should handle the request by responding to both reques
t.Fatalf("failed to write to connection: %v", err) t.Fatalf("failed to write to connection: %v", err)
} }
// Wait for the responses. They can arrive in either order, and we can't tell them // Wait for the responses.
// apart by their request ID, so use the number of headers instead. headers1 := new(eth.BlockHeadersPacket)
resp, err := collectHeaderResponses(conn, 2, func(msg *eth.BlockHeadersPacket) uint64 { if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers1); err != nil {
id := uint64(msg.List.Len()) t.Fatalf("error reading from connection: %v", err)
if id != 2 && id != 3 { }
t.Fatalf("invalid number of headers in response: %d", id) if got, want := headers1.RequestId, request1.RequestId; got != want {
} t.Fatalf("unexpected request id: got %d, want %d", got, want)
return id }
}) headers2 := new(eth.BlockHeadersPacket)
if err != nil { if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers2); err != nil {
t.Fatal(err) t.Fatalf("error reading from connection: %v", err)
}
if got, want := headers2.RequestId, request2.RequestId; got != want {
t.Fatalf("unexpected request id: got %d, want %d", got, want)
} }
// Check if headers match. // Check if headers match.
if err := s.checkHeadersAgainstChain(request1, resp[2]); err != nil { if expected, err := s.chain.GetHeaders(request1); err != nil {
t.Fatal(err) t.Fatalf("failed to get expected block headers: %v", err)
} else if !headersMatch(expected, headers1.BlockHeadersRequest) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers1)
} }
if err := s.checkHeadersAgainstChain(request2, resp[3]); err != nil { if expected, err := s.chain.GetHeaders(request2); err != nil {
t.Fatal(err) t.Fatalf("failed to get expected block headers: %v", err)
} else if !headersMatch(expected, headers2.BlockHeadersRequest) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers2)
} }
} }
func (s *Suite) checkHeadersAgainstChain(req *eth.GetBlockHeadersPacket, resp *eth.BlockHeadersPacket) error {
received2, err := resp.List.Items()
if err != nil {
return fmt.Errorf("invalid headers in response with request ID %v (%d items): %v", resp.RequestId, resp.List.Len(), err)
}
if expected, err := s.chain.GetHeaders(req); err != nil {
return fmt.Errorf("test chain failed to get expected headers for request: %v", err)
} else if !headersMatch(expected, received2) {
return fmt.Errorf("header mismatch for request ID %v (%d items): \nexpected %v \ngot %v", resp.RequestId, resp.List.Len(), expected, resp)
}
return nil
}
// collectResponses waits for n messages of type T on the given connection.
// The messsages are collected according to the 'identity' function.
//
// This function is written in a generic way to handle
func collectHeaderResponses(conn *Conn, n int, identity func(*eth.BlockHeadersPacket) uint64) (map[uint64]*eth.BlockHeadersPacket, error) {
resp := make(map[uint64]*eth.BlockHeadersPacket, n)
for range n {
r := new(eth.BlockHeadersPacket)
if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, r); err != nil {
return resp, fmt.Errorf("read error: %v", err)
}
id := identity(r)
if resp[id] != nil {
return resp, fmt.Errorf("duplicate response %v", r)
}
resp[id] = r
}
return resp, nil
}
func (s *Suite) TestZeroRequestID(t *utesting.T) { func (s *Suite) TestZeroRequestID(t *utesting.T) {
t.Log(`This test sends a GetBlockHeaders message with a request-id of zero, t.Log(`This test sends a GetBlockHeaders message with a request-id of zero,
and expects a response.`) and expects a response.`)
@ -381,8 +356,10 @@ and expects a response.`)
if got, want := headers.RequestId, req.RequestId; got != want { if got, want := headers.RequestId, req.RequestId; got != want {
t.Fatalf("unexpected request id") t.Fatalf("unexpected request id")
} }
if err := s.checkHeadersAgainstChain(req, headers); err != nil { if expected, err := s.chain.GetHeaders(req); err != nil {
t.Fatal(err) t.Fatalf("failed to get expected block headers: %v", err)
} else if !headersMatch(expected, headers.BlockHeadersRequest) {
t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers)
} }
} }
@ -413,8 +390,9 @@ func (s *Suite) TestGetBlockBodies(t *utesting.T) {
if got, want := resp.RequestId, req.RequestId; got != want { if got, want := resp.RequestId, req.RequestId; got != want {
t.Fatalf("unexpected request id in respond", got, want) t.Fatalf("unexpected request id in respond", got, want)
} }
if resp.List.Len() != len(req.GetBlockBodiesRequest) { bodies := resp.BlockBodiesResponse
t.Fatalf("wrong bodies in response: expected %d bodies, got %d", len(req.GetBlockBodiesRequest), resp.List.Len()) if len(bodies) != len(req.GetBlockBodiesRequest) {
t.Fatalf("wrong bodies in response: expected %d bodies, got %d", len(req.GetBlockBodiesRequest), len(bodies))
} }
} }
@ -438,7 +416,7 @@ func (s *Suite) TestGetReceipts(t *utesting.T) {
} }
} }
// Create receipts request. // Create block bodies request.
req := &eth.GetReceiptsPacket{ req := &eth.GetReceiptsPacket{
RequestId: 66, RequestId: 66,
GetReceiptsRequest: (eth.GetReceiptsRequest)(hashes), GetReceiptsRequest: (eth.GetReceiptsRequest)(hashes),
@ -447,15 +425,15 @@ func (s *Suite) TestGetReceipts(t *utesting.T) {
t.Fatalf("could not write to connection: %v", err) t.Fatalf("could not write to connection: %v", err)
} }
// Wait for response. // Wait for response.
resp := new(eth.ReceiptsPacket) resp := new(eth.ReceiptsPacket[*eth.ReceiptList69])
if err := conn.ReadMsg(ethProto, eth.ReceiptsMsg, &resp); err != nil { if err := conn.ReadMsg(ethProto, eth.ReceiptsMsg, &resp); err != nil {
t.Fatalf("error reading block bodies msg: %v", err) t.Fatalf("error reading block bodies msg: %v", err)
} }
if got, want := resp.RequestId, req.RequestId; got != want { if got, want := resp.RequestId, req.RequestId; got != want {
t.Fatalf("unexpected request id in respond", got, want) t.Fatalf("unexpected request id in respond", got, want)
} }
if resp.List.Len() != len(req.GetReceiptsRequest) { if len(resp.List) != len(req.GetReceiptsRequest) {
t.Fatalf("wrong receipts in response: expected %d receipts, got %d", len(req.GetReceiptsRequest), resp.List.Len()) t.Fatalf("wrong bodies in response: expected %d bodies, got %d", len(req.GetReceiptsRequest), len(resp.List))
} }
} }
@ -809,11 +787,7 @@ on another peer connection using GetPooledTransactions.`)
if got, want := msg.RequestId, req.RequestId; got != want { if got, want := msg.RequestId, req.RequestId; got != want {
t.Fatalf("unexpected request id in response: got %d, want %d", got, want) t.Fatalf("unexpected request id in response: got %d, want %d", got, want)
} }
responseTxs, err := msg.List.Items() for _, got := range msg.PooledTransactionsResponse {
if err != nil {
t.Fatalf("invalid transactions in response: %v", err)
}
for _, got := range responseTxs {
if _, exists := set[got.Hash()]; !exists { if _, exists := set[got.Hash()]; !exists {
t.Fatalf("unexpected tx received: %v", got.Hash()) t.Fatalf("unexpected tx received: %v", got.Hash())
} }
@ -913,7 +887,7 @@ func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Tra
from, nonce := s.chain.GetSender(5) from, nonce := s.chain.GetSender(5)
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
// Make blob data, max of 2 blobs per tx. // Make blob data, max of 2 blobs per tx.
blobdata := make([]byte, min(blobs, 2)) blobdata := make([]byte, blobs%3)
for i := range blobdata { for i := range blobdata {
blobdata[i] = discriminator blobdata[i] = discriminator
blobs -= 1 blobs -= 1
@ -985,9 +959,7 @@ func (s *Suite) TestBlobViolations(t *utesting.T) {
if err := conn.ReadMsg(ethProto, eth.GetPooledTransactionsMsg, req); err != nil { if err := conn.ReadMsg(ethProto, eth.GetPooledTransactionsMsg, req); err != nil {
t.Fatalf("reading pooled tx request failed: %v", err) t.Fatalf("reading pooled tx request failed: %v", err)
} }
resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, PooledTransactionsResponse: test.resp}
encTxs, _ := rlp.EncodeToRawList(test.resp)
resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, List: encTxs}
if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil { if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil {
t.Fatalf("writing pooled tx response failed: %v", err) t.Fatalf("writing pooled tx response failed: %v", err)
} }
@ -1115,8 +1087,7 @@ func (s *Suite) testBadBlobTx(t *utesting.T, tx *types.Transaction, badTx *types
// the good peer is connected, and has announced the tx. // the good peer is connected, and has announced the tx.
// proceed to send the incorrect one from the bad peer. // proceed to send the incorrect one from the bad peer.
encTxs, _ := rlp.EncodeToRawList([]*types.Transaction{badTx}) resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, PooledTransactionsResponse: eth.PooledTransactionsResponse(types.Transactions{badTx})}
resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, List: encTxs}
if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil { if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil {
errc <- fmt.Errorf("writing pooled tx response failed: %v", err) errc <- fmt.Errorf("writing pooled tx response failed: %v", err)
return return
@ -1162,10 +1133,7 @@ func (s *Suite) testBadBlobTx(t *utesting.T, tx *types.Transaction, badTx *types
// transmit the same tx but with correct sidecar from the good peer. // transmit the same tx but with correct sidecar from the good peer.
var req *eth.GetPooledTransactionsPacket var req *eth.GetPooledTransactionsPacket
ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) req, err = readUntil[eth.GetPooledTransactionsPacket](context.Background(), conn)
defer cancel()
req, err = readUntil[eth.GetPooledTransactionsPacket](ctx, conn)
if err != nil { if err != nil {
errc <- fmt.Errorf("reading pooled tx request failed: %v", err) errc <- fmt.Errorf("reading pooled tx request failed: %v", err)
return return
@ -1176,8 +1144,7 @@ func (s *Suite) testBadBlobTx(t *utesting.T, tx *types.Transaction, badTx *types
return return
} }
encTxs, _ := rlp.EncodeToRawList([]*types.Transaction{tx}) resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, PooledTransactionsResponse: eth.PooledTransactionsResponse(types.Transactions{tx})}
resp := eth.PooledTransactionsPacket{RequestId: req.RequestId, List: encTxs}
if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil { if err := conn.Write(ethProto, eth.PooledTransactionsMsg, resp); err != nil {
errc <- fmt.Errorf("writing pooled tx response failed: %v", err) errc <- fmt.Errorf("writing pooled tx response failed: %v", err)
return return

Binary file not shown.

View file

@ -1,27 +1,20 @@
{ {
"HIVE_CANCUN_BLOB_BASE_FEE_UPDATE_FRACTION": "3338477", "HIVE_CANCUN_TIMESTAMP": "840",
"HIVE_CANCUN_BLOB_MAX": "6",
"HIVE_CANCUN_BLOB_TARGET": "3",
"HIVE_CANCUN_TIMESTAMP": "60",
"HIVE_CHAIN_ID": "3503995874084926", "HIVE_CHAIN_ID": "3503995874084926",
"HIVE_FORK_ARROW_GLACIER": "0", "HIVE_FORK_ARROW_GLACIER": "60",
"HIVE_FORK_BERLIN": "0", "HIVE_FORK_BERLIN": "48",
"HIVE_FORK_BYZANTIUM": "0", "HIVE_FORK_BYZANTIUM": "18",
"HIVE_FORK_CONSTANTINOPLE": "0", "HIVE_FORK_CONSTANTINOPLE": "24",
"HIVE_FORK_GRAY_GLACIER": "0", "HIVE_FORK_GRAY_GLACIER": "66",
"HIVE_FORK_HOMESTEAD": "0", "HIVE_FORK_HOMESTEAD": "0",
"HIVE_FORK_ISTANBUL": "0", "HIVE_FORK_ISTANBUL": "36",
"HIVE_FORK_LONDON": "0", "HIVE_FORK_LONDON": "54",
"HIVE_FORK_MUIR_GLACIER": "0", "HIVE_FORK_MUIR_GLACIER": "42",
"HIVE_FORK_PETERSBURG": "0", "HIVE_FORK_PETERSBURG": "30",
"HIVE_FORK_SPURIOUS": "0", "HIVE_FORK_SPURIOUS": "12",
"HIVE_FORK_TANGERINE": "0", "HIVE_FORK_TANGERINE": "6",
"HIVE_MERGE_BLOCK_ID": "0", "HIVE_MERGE_BLOCK_ID": "72",
"HIVE_NETWORK_ID": "3503995874084926", "HIVE_NETWORK_ID": "3503995874084926",
"HIVE_PRAGUE_BLOB_BASE_FEE_UPDATE_FRACTION": "5007716", "HIVE_SHANGHAI_TIMESTAMP": "780",
"HIVE_PRAGUE_BLOB_MAX": "9", "HIVE_TERMINAL_TOTAL_DIFFICULTY": "9454784"
"HIVE_PRAGUE_BLOB_TARGET": "6",
"HIVE_PRAGUE_TIMESTAMP": "120",
"HIVE_SHANGHAI_TIMESTAMP": "0",
"HIVE_TERMINAL_TOTAL_DIFFICULTY": "131072"
} }

View file

@ -2,35 +2,28 @@
"config": { "config": {
"chainId": 3503995874084926, "chainId": 3503995874084926,
"homesteadBlock": 0, "homesteadBlock": 0,
"eip150Block": 0, "eip150Block": 6,
"eip155Block": 0, "eip155Block": 12,
"eip158Block": 0, "eip158Block": 12,
"byzantiumBlock": 0, "byzantiumBlock": 18,
"constantinopleBlock": 0, "constantinopleBlock": 24,
"petersburgBlock": 0, "petersburgBlock": 30,
"istanbulBlock": 0, "istanbulBlock": 36,
"muirGlacierBlock": 0, "muirGlacierBlock": 42,
"berlinBlock": 0, "berlinBlock": 48,
"londonBlock": 0, "londonBlock": 54,
"arrowGlacierBlock": 0, "arrowGlacierBlock": 60,
"grayGlacierBlock": 0, "grayGlacierBlock": 66,
"mergeNetsplitBlock": 0, "mergeNetsplitBlock": 72,
"shanghaiTime": 0, "shanghaiTime": 780,
"cancunTime": 60, "cancunTime": 840,
"pragueTime": 120, "terminalTotalDifficulty": 9454784,
"terminalTotalDifficulty": 131072,
"depositContractAddress": "0x0000000000000000000000000000000000000000",
"ethash": {}, "ethash": {},
"blobSchedule": { "blobSchedule": {
"cancun": { "cancun": {
"target": 3, "target": 3,
"max": 6, "max": 6,
"baseFeeUpdateFraction": 3338477 "baseFeeUpdateFraction": 3338477
},
"prague": {
"target": 6,
"max": 9,
"baseFeeUpdateFraction": 5007716
} }
} }
}, },
@ -42,18 +35,6 @@
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000",
"alloc": { "alloc": {
"00000961ef480eb55e80d19ad83579a64c007002": {
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd",
"balance": "0x1"
},
"0000bbddc7ce488642fb579f8b00f3a590007251": {
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd",
"balance": "0x1"
},
"0000f90827f1c53a10cb7a02335b175320002935": {
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500",
"balance": "0x1"
},
"000f3df6d732807ef1319fb7b8bb8522d0beac02": { "000f3df6d732807ef1319fb7b8bb8522d0beac02": {
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500",
"balance": "0x2a" "balance": "0x2a"
@ -100,10 +81,6 @@
"7435ed30a8b4aeb0877cef0c6e8cffe834eb865f": { "7435ed30a8b4aeb0877cef0c6e8cffe834eb865f": {
"balance": "0xc097ce7bc90715b34b9f1000000000" "balance": "0xc097ce7bc90715b34b9f1000000000"
}, },
"7dcd17433742f4c0ca53122ab541d0ba67fc27df": {
"code": "0x3680600080376000206000548082558060010160005560005263656d697460206000a2",
"balance": "0x0"
},
"83c7e323d189f18725ac510004fdc2941f8c4a78": { "83c7e323d189f18725ac510004fdc2941f8c4a78": {
"balance": "0xc097ce7bc90715b34b9f1000000000" "balance": "0xc097ce7bc90715b34b9f1000000000"
}, },
@ -135,7 +112,7 @@
"number": "0x0", "number": "0x0",
"gasUsed": "0x0", "gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": "0x3b9aca00", "baseFeePerGas": null,
"excessBlobGas": null, "excessBlobGas": null,
"blobGasUsed": null "blobGasUsed": null
} }

View file

@ -1,16 +1,16 @@
{ {
"parentHash": "0x65151b101682b54cd08ba226f640c14c86176865ff9bfc57e0147dadaeac34bb", "parentHash": "0x96a73007443980c5e0985dfbb45279aa496dadea16918ad42c65c0bf8122ec39",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"miner": "0x0000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000",
"stateRoot": "0xce423ebc60fc7764a43f09f1fe3ae61eef25e3eb8d09b1108f7e7eb77dfff5e6", "stateRoot": "0xea4c1f4d9fa8664c22574c5b2f948a78c4b1a753cebc1861e7fb5b1aa21c5a94",
"transactionsRoot": "0x7ec1ae3989efa75d7bcc766e5e2443afa8a89a5fda42ebba90050e7e702980f7", "transactionsRoot": "0xecda39025fc4c609ce778d75eed0aa53b65ce1e3d1373b34bad8578cc31e5b48",
"receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x0", "difficulty": "0x0",
"number": "0x258", "number": "0x1f4",
"gasLimit": "0x23f3e20", "gasLimit": "0x47e7c40",
"gasUsed": "0x19d36", "gasUsed": "0x5208",
"timestamp": "0x1770", "timestamp": "0x1388",
"extraData": "0x", "extraData": "0x",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x0000000000000000", "nonce": "0x0000000000000000",
@ -18,7 +18,6 @@
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"blobGasUsed": "0x0", "blobGasUsed": "0x0",
"excessBlobGas": "0x0", "excessBlobGas": "0x0",
"parentBeaconBlockRoot": "0xf5003fc8f92358e790a114bce93ce1d9c283c85e1787f8d7d56714d3489b49e6", "parentBeaconBlockRoot": "0xf653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c",
"requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "hash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7"
"hash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0"
} }

View file

@ -1,12 +1,12 @@
{ {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": "fcu600", "id": "fcu500",
"method": "engine_forkchoiceUpdatedV3", "method": "engine_forkchoiceUpdatedV3",
"params": [ "params": [
{ {
"headBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0", "headBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7",
"safeBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0", "safeBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7",
"finalizedBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0" "finalizedBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7"
}, },
null null
] ]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,6 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/eth"
"github.com/ethereum/go-ethereum/internal/utesting" "github.com/ethereum/go-ethereum/internal/utesting"
"github.com/ethereum/go-ethereum/rlp"
) )
// sendTxs sends the given transactions to the node and // sendTxs sends the given transactions to the node and
@ -52,8 +51,7 @@ func (s *Suite) sendTxs(t *utesting.T, txs []*types.Transaction) error {
return fmt.Errorf("peering failed: %v", err) return fmt.Errorf("peering failed: %v", err)
} }
encTxs, _ := rlp.EncodeToRawList(txs) if err = sendConn.Write(ethProto, eth.TransactionsMsg, eth.TransactionsPacket(txs)); err != nil {
if err = sendConn.Write(ethProto, eth.TransactionsMsg, eth.TransactionsPacket{RawList: encTxs}); err != nil {
return fmt.Errorf("failed to write message to connection: %v", err) return fmt.Errorf("failed to write message to connection: %v", err)
} }
@ -70,8 +68,7 @@ func (s *Suite) sendTxs(t *utesting.T, txs []*types.Transaction) error {
} }
switch msg := msg.(type) { switch msg := msg.(type) {
case *eth.TransactionsPacket: case *eth.TransactionsPacket:
txs, _ := msg.Items() for _, tx := range *msg {
for _, tx := range txs {
got[tx.Hash()] = true got[tx.Hash()] = true
} }
case *eth.NewPooledTransactionHashesPacket: case *eth.NewPooledTransactionHashesPacket:
@ -83,10 +80,9 @@ func (s *Suite) sendTxs(t *utesting.T, txs []*types.Transaction) error {
if err != nil { if err != nil {
t.Logf("invalid GetBlockHeaders request: %v", err) t.Logf("invalid GetBlockHeaders request: %v", err)
} }
encHeaders, _ := rlp.EncodeToRawList(headers)
recvConn.Write(ethProto, eth.BlockHeadersMsg, &eth.BlockHeadersPacket{ recvConn.Write(ethProto, eth.BlockHeadersMsg, &eth.BlockHeadersPacket{
RequestId: msg.RequestId, RequestId: msg.RequestId,
List: encHeaders, BlockHeadersRequest: headers,
}) })
default: default:
return fmt.Errorf("unexpected eth wire msg: %s", pretty.Sdump(msg)) return fmt.Errorf("unexpected eth wire msg: %s", pretty.Sdump(msg))
@ -171,10 +167,9 @@ func (s *Suite) sendInvalidTxs(t *utesting.T, txs []*types.Transaction) error {
if err != nil { if err != nil {
t.Logf("invalid GetBlockHeaders request: %v", err) t.Logf("invalid GetBlockHeaders request: %v", err)
} }
encHeaders, _ := rlp.EncodeToRawList(headers)
recvConn.Write(ethProto, eth.BlockHeadersMsg, &eth.BlockHeadersPacket{ recvConn.Write(ethProto, eth.BlockHeadersMsg, &eth.BlockHeadersPacket{
RequestId: msg.RequestId, RequestId: msg.RequestId,
List: encHeaders, BlockHeadersRequest: headers,
}) })
default: default:
return fmt.Errorf("unexpected eth message: %v", pretty.Sdump(msg)) return fmt.Errorf("unexpected eth message: %v", pretty.Sdump(msg))

View file

@ -52,7 +52,7 @@ func (s *Suite) AllTests() []utesting.Test {
{Name: "Ping", Fn: s.TestPing}, {Name: "Ping", Fn: s.TestPing},
{Name: "PingLargeRequestID", Fn: s.TestPingLargeRequestID}, {Name: "PingLargeRequestID", Fn: s.TestPingLargeRequestID},
{Name: "PingMultiIP", Fn: s.TestPingMultiIP}, {Name: "PingMultiIP", Fn: s.TestPingMultiIP},
{Name: "HandshakeResend", Fn: s.TestHandshakeResend}, {Name: "PingHandshakeInterrupted", Fn: s.TestPingHandshakeInterrupted},
{Name: "TalkRequest", Fn: s.TestTalkRequest}, {Name: "TalkRequest", Fn: s.TestTalkRequest},
{Name: "FindnodeZeroDistance", Fn: s.TestFindnodeZeroDistance}, {Name: "FindnodeZeroDistance", Fn: s.TestFindnodeZeroDistance},
{Name: "FindnodeResults", Fn: s.TestFindnodeResults}, {Name: "FindnodeResults", Fn: s.TestFindnodeResults},
@ -158,20 +158,22 @@ the attempt from a different IP.`)
} }
} }
// TestHandshakeResend starts a handshake, but doesn't finish it and sends a second ordinary message // TestPingHandshakeInterrupted starts a handshake, but doesn't finish it and sends a second ordinary message
// packet instead of a handshake message packet. The remote node should repeat the previous WHOAREYOU // packet instead of a handshake message packet. The remote node should respond with
// challenge for the first PING. // another WHOAREYOU challenge for the second packet.
func (s *Suite) TestHandshakeResend(t *utesting.T) { func (s *Suite) TestPingHandshakeInterrupted(t *utesting.T) {
t.Log(`TestPingHandshakeInterrupted starts a handshake, but doesn't finish it and sends a second ordinary message
packet instead of a handshake message packet. The remote node should respond with
another WHOAREYOU challenge for the second packet.`)
conn, l1 := s.listen1(t) conn, l1 := s.listen1(t)
defer conn.close() defer conn.close()
// First PING triggers challenge. // First PING triggers challenge.
ping := &v5wire.Ping{ReqID: conn.nextReqID()} ping := &v5wire.Ping{ReqID: conn.nextReqID()}
conn.write(l1, ping, nil) conn.write(l1, ping, nil)
var challenge1 *v5wire.Whoareyou
switch resp := conn.read(l1).(type) { switch resp := conn.read(l1).(type) {
case *v5wire.Whoareyou: case *v5wire.Whoareyou:
challenge1 = resp
t.Logf("got WHOAREYOU for PING") t.Logf("got WHOAREYOU for PING")
default: default:
t.Fatal("expected WHOAREYOU, got", resp) t.Fatal("expected WHOAREYOU, got", resp)
@ -179,16 +181,9 @@ func (s *Suite) TestHandshakeResend(t *utesting.T) {
// Send second PING. // Send second PING.
ping2 := &v5wire.Ping{ReqID: conn.nextReqID()} ping2 := &v5wire.Ping{ReqID: conn.nextReqID()}
conn.write(l1, ping2, nil) switch resp := conn.reqresp(l1, ping2).(type) {
switch resp := conn.read(l1).(type) { case *v5wire.Pong:
case *v5wire.Whoareyou: checkPong(t, resp, ping2, l1)
if resp.Nonce != challenge1.Nonce {
t.Fatalf("wrong nonce %x in WHOAREYOU (want %x)", resp.Nonce[:], challenge1.Nonce[:])
}
if !bytes.Equal(resp.ChallengeData, challenge1.ChallengeData) {
t.Fatalf("wrong ChallengeData in resent WHOAREYOU (want %x)", resp.ChallengeData, challenge1.ChallengeData)
}
resp.Node = conn.remote
default: default:
t.Fatal("expected WHOAREYOU, got", resp) t.Fatal("expected WHOAREYOU, got", resp)
} }

View file

@ -143,6 +143,9 @@ type testParams struct {
func cliTestParams(ctx *cli.Context) *testParams { func cliTestParams(ctx *cli.Context) *testParams {
nodeStr := ctx.String(testNodeFlag.Name) nodeStr := ctx.String(testNodeFlag.Name)
if nodeStr == "" {
exit(fmt.Errorf("missing -%s", testNodeFlag.Name))
}
node, err := parseNode(nodeStr) node, err := parseNode(nodeStr)
if err != nil { if err != nil {
exit(err) exit(err)
@ -153,5 +156,14 @@ func cliTestParams(ctx *cli.Context) *testParams {
jwt: ctx.String(testNodeJWTFlag.Name), jwt: ctx.String(testNodeJWTFlag.Name),
chainDir: ctx.String(testChainDirFlag.Name), chainDir: ctx.String(testChainDirFlag.Name),
} }
if p.engineAPI == "" {
exit(fmt.Errorf("missing -%s", testNodeEngineFlag.Name))
}
if p.jwt == "" {
exit(fmt.Errorf("missing -%s", testNodeJWTFlag.Name))
}
if p.chainDir == "" {
exit(fmt.Errorf("missing -%s", testChainDirFlag.Name))
}
return &p return &p
} }

View file

@ -39,29 +39,26 @@ var (
} }
// for eth/snap tests // for eth/snap tests
testChainDirFlag = &cli.PathFlag{ testChainDirFlag = &cli.StringFlag{
Name: "chain", Name: "chain",
Usage: "Test chain directory (required)", Usage: "Test chain directory (required)",
Category: flags.TestingCategory, Category: flags.TestingCategory,
Required: true,
} }
testNodeFlag = &cli.StringFlag{ testNodeFlag = &cli.StringFlag{
Name: "node", Name: "node",
Usage: "Peer-to-Peer endpoint (ENR) of the test node (required)", Usage: "Peer-to-Peer endpoint (ENR) of the test node (required)",
Category: flags.TestingCategory, Category: flags.TestingCategory,
Required: true,
} }
testNodeJWTFlag = &cli.StringFlag{ testNodeJWTFlag = &cli.StringFlag{
Name: "jwtsecret", Name: "jwtsecret",
Usage: "JWT secret for the engine API of the test node (required)", Usage: "JWT secret for the engine API of the test node (required)",
Category: flags.TestingCategory, Category: flags.TestingCategory,
Required: true, Value: "0x7365637265747365637265747365637265747365637265747365637265747365",
} }
testNodeEngineFlag = &cli.StringFlag{ testNodeEngineFlag = &cli.StringFlag{
Name: "engineapi", Name: "engineapi",
Usage: "Engine API endpoint of the test node (required)", Usage: "Engine API endpoint of the test node (required)",
Category: flags.TestingCategory, Category: flags.TestingCategory,
Required: true,
} }
// These two are specific to the discovery tests. // These two are specific to the discovery tests.

View file

@ -30,8 +30,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/internal/era" "github.com/ethereum/go-ethereum/internal/era"
"github.com/ethereum/go-ethereum/internal/era/execdb"
"github.com/ethereum/go-ethereum/internal/era/onedb"
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/internal/flags"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -55,7 +53,7 @@ var (
eraSizeFlag = &cli.IntFlag{ eraSizeFlag = &cli.IntFlag{
Name: "size", Name: "size",
Usage: "number of blocks per era", Usage: "number of blocks per era",
Value: era.MaxSize, Value: era.MaxEra1Size,
} }
txsFlag = &cli.BoolFlag{ txsFlag = &cli.BoolFlag{
Name: "txs", Name: "txs",
@ -133,7 +131,7 @@ func block(ctx *cli.Context) error {
return nil return nil
} }
// info prints some high-level information about the era file. // info prints some high-level information about the era1 file.
func info(ctx *cli.Context) error { func info(ctx *cli.Context) error {
epoch, err := strconv.ParseUint(ctx.Args().First(), 10, 64) epoch, err := strconv.ParseUint(ctx.Args().First(), 10, 64)
if err != nil { if err != nil {
@ -144,34 +142,33 @@ func info(ctx *cli.Context) error {
return err return err
} }
defer e.Close() defer e.Close()
var ( acc, err := e.Accumulator()
accHex string if err != nil {
tdStr string return fmt.Errorf("error reading accumulator: %w", err)
)
if acc, err := e.Accumulator(); err == nil {
accHex = acc.Hex()
} }
if td, err := e.InitialTD(); err == nil { td, err := e.InitialTD()
tdStr = td.String() if err != nil {
return fmt.Errorf("error reading total difficulty: %w", err)
} }
info := struct { info := struct {
Accumulator string `json:"accumulator,omitempty"` Accumulator common.Hash `json:"accumulator"`
TotalDifficulty string `json:"totalDifficulty,omitempty"` TotalDifficulty *big.Int `json:"totalDifficulty"`
StartBlock uint64 `json:"startBlock"` StartBlock uint64 `json:"startBlock"`
Count uint64 `json:"count"` Count uint64 `json:"count"`
}{ }{
accHex, tdStr, e.Start(), e.Count(), acc, td, e.Start(), e.Count(),
} }
b, _ := json.MarshalIndent(info, "", " ") b, _ := json.MarshalIndent(info, "", " ")
fmt.Println(string(b)) fmt.Println(string(b))
return nil return nil
} }
// open opens an era file at a certain epoch. // open opens an era1 file at a certain epoch.
func open(ctx *cli.Context, epoch uint64) (era.Era, error) { func open(ctx *cli.Context, epoch uint64) (*era.Era, error) {
dir := ctx.String(dirFlag.Name) var (
network := ctx.String(networkFlag.Name) dir = ctx.String(dirFlag.Name)
network = ctx.String(networkFlag.Name)
)
entries, err := era.ReadDir(dir, network) entries, err := era.ReadDir(dir, network)
if err != nil { if err != nil {
return nil, fmt.Errorf("error reading era dir: %w", err) return nil, fmt.Errorf("error reading era dir: %w", err)
@ -179,28 +176,7 @@ func open(ctx *cli.Context, epoch uint64) (era.Era, error) {
if epoch >= uint64(len(entries)) { if epoch >= uint64(len(entries)) {
return nil, fmt.Errorf("epoch out-of-bounds: last %d, want %d", len(entries)-1, epoch) return nil, fmt.Errorf("epoch out-of-bounds: last %d, want %d", len(entries)-1, epoch)
} }
path := filepath.Join(dir, entries[epoch]) return era.Open(filepath.Join(dir, entries[epoch]))
return openByPath(path)
}
// openByPath tries to open a single file as either eraE or era1 based on extension,
// falling back to the other reader if needed.
func openByPath(path string) (era.Era, error) {
switch strings.ToLower(filepath.Ext(path)) {
case ".erae":
if e, err := execdb.Open(path); err != nil {
return nil, err
} else {
return e, nil
}
case ".era1":
if e, err := onedb.Open(path); err != nil {
return nil, err
} else {
return e, nil
}
}
return nil, fmt.Errorf("unsupported or unreadable era file: %s", path)
} }
// verify checks each era1 file in a directory to ensure it is well-formed and // verify checks each era1 file in a directory to ensure it is well-formed and
@ -227,58 +203,18 @@ func verify(ctx *cli.Context) error {
return fmt.Errorf("error reading %s: %w", dir, err) return fmt.Errorf("error reading %s: %w", dir, err)
} }
// Build the verification list respecting the rule: if len(entries) != len(roots) {
// era1: must have accumulator, always verify return errors.New("number of era1 files should match the number of accumulator hashes")
// erae: verify only if accumulator exists (pre-merge)
// Build list of files to verify.
verify := make([]string, 0, len(entries))
for _, name := range entries {
path := filepath.Join(dir, name)
ext := strings.ToLower(filepath.Ext(name))
switch ext {
case ".era1":
e, err := onedb.Open(path)
if err != nil {
return fmt.Errorf("error opening era1 file %s: %w", name, err)
}
_, accErr := e.Accumulator()
e.Close()
if accErr != nil {
return fmt.Errorf("era1 file %s missing accumulator: %w", name, accErr)
}
verify = append(verify, path)
case ".erae":
e, err := execdb.Open(path)
if err != nil {
return fmt.Errorf("error opening erae file %s: %w", name, err)
}
_, accErr := e.Accumulator()
e.Close()
if accErr == nil {
verify = append(verify, path) // pre-merge only
}
default:
return fmt.Errorf("unsupported era file: %s", name)
}
}
if len(verify) != len(roots) {
return fmt.Errorf("mismatch between eras to verify (%d) and provided roots (%d)", len(verify), len(roots))
} }
// Verify each epoch matches the expected root. // Verify each epoch matches the expected root.
for i, want := range roots { for i, want := range roots {
// Wrap in function so defers don't stack. // Wrap in function so defers don't stack.
err := func() error { err := func() error {
path := verify[i] name := entries[i]
name := filepath.Base(path) e, err := era.Open(filepath.Join(dir, name))
e, err := openByPath(path)
if err != nil { if err != nil {
return fmt.Errorf("error opening era file %s: %w", name, err) return fmt.Errorf("error opening era1 file %s: %w", name, err)
} }
defer e.Close() defer e.Close()
// Read accumulator and check against expected. // Read accumulator and check against expected.
@ -307,7 +243,7 @@ func verify(ctx *cli.Context) error {
} }
// checkAccumulator verifies the accumulator matches the data in the Era. // checkAccumulator verifies the accumulator matches the data in the Era.
func checkAccumulator(e era.Era) error { func checkAccumulator(e *era.Era) error {
var ( var (
err error err error
want common.Hash want common.Hash
@ -321,7 +257,7 @@ func checkAccumulator(e era.Era) error {
if td, err = e.InitialTD(); err != nil { if td, err = e.InitialTD(); err != nil {
return fmt.Errorf("error reading total difficulty: %w", err) return fmt.Errorf("error reading total difficulty: %w", err)
} }
it, err := e.Iterator() it, err := era.NewIterator(e)
if err != nil { if err != nil {
return fmt.Errorf("error making era iterator: %w", err) return fmt.Errorf("error making era iterator: %w", err)
} }
@ -338,10 +274,10 @@ func checkAccumulator(e era.Era) error {
for it.Next() { for it.Next() {
// 1) next() walks the block index, so we're able to implicitly verify it. // 1) next() walks the block index, so we're able to implicitly verify it.
if it.Error() != nil { if it.Error() != nil {
return fmt.Errorf("error reading block %d: %w", it.Number(), it.Error()) return fmt.Errorf("error reading block %d: %w", it.Number(), err)
} }
block, receipts, err := it.BlockAndReceipts() block, receipts, err := it.BlockAndReceipts()
if err != nil { if it.Error() != nil {
return fmt.Errorf("error reading block %d: %w", it.Number(), err) return fmt.Errorf("error reading block %d: %w", it.Number(), err)
} }
// 2) recompute tx root and verify against header. // 2) recompute tx root and verify against header.
@ -354,16 +290,9 @@ func checkAccumulator(e era.Era) error {
if rr != block.ReceiptHash() { if rr != block.ReceiptHash() {
return fmt.Errorf("receipt root in block %d mismatch: want %s, got %s", block.NumberU64(), block.ReceiptHash(), rr) return fmt.Errorf("receipt root in block %d mismatch: want %s, got %s", block.NumberU64(), block.ReceiptHash(), rr)
} }
// Only include pre-merge blocks in accumulator calculation. hashes = append(hashes, block.Hash())
// Post-merge blocks have difficulty == 0. td.Add(td, block.Difficulty())
if block.Difficulty().Sign() > 0 { tds = append(tds, new(big.Int).Set(td))
hashes = append(hashes, block.Hash())
td.Add(td, block.Difficulty())
tds = append(tds, new(big.Int).Set(td))
}
}
if it.Error() != nil {
return fmt.Errorf("error reading block %d: %w", it.Number(), it.Error())
} }
// 4+5) Verify accumulator and total difficulty. // 4+5) Verify accumulator and total difficulty.
got, err := era.ComputeAccumulator(hashes, tds) got, err := era.ComputeAccumulator(hashes, tds)

View file

@ -17,18 +17,16 @@
package main package main
import ( import (
"bufio"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"maps" "maps"
"os" "os"
"regexp" "regexp"
"slices" "slices"
"github.com/ethereum/go-ethereum/common"
"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/log"
"github.com/ethereum/go-ethereum/tests" "github.com/ethereum/go-ethereum/tests"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@ -36,52 +34,33 @@ import (
var blockTestCommand = &cli.Command{ var blockTestCommand = &cli.Command{
Action: blockTestCmd, Action: blockTestCmd,
Name: "blocktest", Name: "blocktest",
Usage: "Executes the given blockchain tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).", Usage: "Executes the given blockchain tests",
ArgsUsage: "<path>", ArgsUsage: "<path>",
Flags: slices.Concat([]cli.Flag{ Flags: slices.Concat([]cli.Flag{
DumpFlag, DumpFlag,
HumanReadableFlag, HumanReadableFlag,
RunFlag, RunFlag,
WitnessCrossCheckFlag, WitnessCrossCheckFlag,
FuzzFlag,
}, traceFlags), }, traceFlags),
} }
func blockTestCmd(ctx *cli.Context) error { func blockTestCmd(ctx *cli.Context) error {
path := ctx.Args().First() path := ctx.Args().First()
if len(path) == 0 {
// If path is provided, run the tests at that path. return errors.New("path argument required")
if len(path) != 0 {
var (
collected = collectFiles(path)
results []testResult
)
for _, fname := range collected {
r, err := runBlockTest(ctx, fname)
if err != nil {
return err
}
results = append(results, r...)
}
report(ctx, results)
return nil
} }
// Otherwise, read filenames from stdin and execute back-to-back. var (
scanner := bufio.NewScanner(os.Stdin) collected = collectFiles(path)
for scanner.Scan() { results []testResult
fname := scanner.Text() )
if len(fname) == 0 { for _, fname := range collected {
return nil r, err := runBlockTest(ctx, fname)
}
results, err := runBlockTest(ctx, fname)
if err != nil { if err != nil {
return err return err
} }
// During fuzzing, we report the result after every block results = append(results, r...)
if !ctx.IsSet(FuzzFlag.Name) {
report(ctx, results)
}
} }
report(ctx, results)
return nil return nil
} }
@ -100,11 +79,6 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
} }
tracer := tracerFromFlags(ctx) tracer := tracerFromFlags(ctx)
// Suppress INFO logs during fuzzing
if ctx.IsSet(FuzzFlag.Name) {
log.SetDefault(log.NewLogger(log.DiscardHandler()))
}
// Pull out keys to sort and ensure tests are run in order. // Pull out keys to sort and ensure tests are run in order.
keys := slices.Sorted(maps.Keys(tests)) keys := slices.Sorted(maps.Keys(tests))
@ -114,35 +88,16 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) {
if !re.MatchString(name) { if !re.MatchString(name) {
continue continue
} }
test := tests[name]
result := &testResult{Name: name, Pass: true} result := &testResult{Name: name, Pass: true}
var finalRoot *common.Hash if err := tests[name].Run(false, rawdb.HashScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
if err := test.Run(false, rawdb.PathScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) {
if ctx.Bool(DumpFlag.Name) { if ctx.Bool(DumpFlag.Name) {
if s, _ := chain.State(); s != nil { if s, _ := chain.State(); s != nil {
result.State = dump(s) result.State = dump(s)
} }
} }
// Capture final state root for end marker
if chain != nil {
root := chain.CurrentBlock().Root
finalRoot = &root
}
}); err != nil { }); err != nil {
result.Pass, result.Error = false, err.Error() result.Pass, result.Error = false, err.Error()
} }
// Always assign fork (regardless of pass/fail or tracer)
result.Fork = test.Network()
// Assign root if test succeeded
if result.Pass && finalRoot != nil {
result.Root = finalRoot
}
// When fuzzing, write results after every block
if ctx.IsSet(FuzzFlag.Name) {
report(ctx, []testResult{*result})
}
results = append(results, *result) results = append(results, *result)
} }
return results, nil return results, nil

View file

@ -56,7 +56,6 @@ type header struct {
BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"` BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"`
ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"` ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
SlotNumber *uint64 `json:"slotNumber" rlp:"optional"`
} }
type headerMarshaling struct { type headerMarshaling struct {
@ -69,7 +68,6 @@ type headerMarshaling struct {
BaseFee *math.HexOrDecimal256 BaseFee *math.HexOrDecimal256
BlobGasUsed *math.HexOrDecimal64 BlobGasUsed *math.HexOrDecimal64
ExcessBlobGas *math.HexOrDecimal64 ExcessBlobGas *math.HexOrDecimal64
SlotNumber *math.HexOrDecimal64
} }
type bbInput struct { type bbInput struct {
@ -138,7 +136,6 @@ func (i *bbInput) ToBlock() *types.Block {
BlobGasUsed: i.Header.BlobGasUsed, BlobGasUsed: i.Header.BlobGasUsed,
ExcessBlobGas: i.Header.ExcessBlobGas, ExcessBlobGas: i.Header.ExcessBlobGas,
ParentBeaconRoot: i.Header.ParentBeaconBlockRoot, ParentBeaconRoot: i.Header.ParentBeaconBlockRoot,
SlotNumber: i.Header.SlotNumber,
} }
// Fill optional values. // Fill optional values.

View file

@ -18,7 +18,6 @@ package t8ntool
import ( import (
"fmt" "fmt"
stdmath "math"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -33,7 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto/keccak" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -41,12 +40,12 @@ import (
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"golang.org/x/crypto/sha3"
) )
type Prestate struct { type Prestate struct {
Env stEnv `json:"env"` Env stEnv `json:"env"`
Pre types.GenesisAlloc `json:"pre"` Pre types.GenesisAlloc `json:"pre"`
TreeLeaves map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"`
} }
//go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go //go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go
@ -102,7 +101,6 @@ type stEnv struct {
ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"` ParentExcessBlobGas *uint64 `json:"parentExcessBlobGas,omitempty"`
ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"` ParentBlobGasUsed *uint64 `json:"parentBlobGasUsed,omitempty"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *uint64 `json:"slotNumber"`
} }
type stEnvMarshaling struct { type stEnvMarshaling struct {
@ -121,7 +119,6 @@ type stEnvMarshaling struct {
ExcessBlobGas *math.HexOrDecimal64 ExcessBlobGas *math.HexOrDecimal64
ParentExcessBlobGas *math.HexOrDecimal64 ParentExcessBlobGas *math.HexOrDecimal64
ParentBlobGasUsed *math.HexOrDecimal64 ParentBlobGasUsed *math.HexOrDecimal64
SlotNumber *math.HexOrDecimal64
} }
type rejectedTx struct { type rejectedTx struct {
@ -146,8 +143,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
return h return h
} }
var ( var (
isEIP4762 = chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre)
statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre, isEIP4762)
signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp)
gaspool = new(core.GasPool) gaspool = new(core.GasPool)
blockHash = common.Hash{0x13, 0x37} blockHash = common.Hash{0x13, 0x37}
@ -156,6 +152,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
gasUsed = uint64(0) gasUsed = uint64(0)
blobGasUsed = uint64(0) blobGasUsed = uint64(0)
receipts = make(types.Receipts, 0) receipts = make(types.Receipts, 0)
txIndex = 0
) )
gaspool.AddGas(pre.Env.GasLimit) gaspool.AddGas(pre.Env.GasLimit)
vmContext := vm.BlockContext{ vmContext := vm.BlockContext{
@ -196,8 +193,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
Time: pre.Env.ParentTimestamp, Time: pre.Env.ParentTimestamp,
ExcessBlobGas: pre.Env.ParentExcessBlobGas, ExcessBlobGas: pre.Env.ParentExcessBlobGas,
BlobGasUsed: pre.Env.ParentBlobGasUsed, BlobGasUsed: pre.Env.ParentBlobGasUsed,
BaseFee: pre.Env.ParentBaseFee,
SlotNumber: pre.Env.SlotNumber,
} }
header := &types.Header{ header := &types.Header{
Time: pre.Env.Timestamp, Time: pre.Env.Timestamp,
@ -255,32 +250,75 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
continue continue
} }
} }
statedb.SetTxContext(tx.Hash(), len(receipts)) statedb.SetTxContext(tx.Hash(), txIndex)
var ( var (
snapshot = statedb.Snapshot() snapshot = statedb.Snapshot()
prevGas = gaspool.Gas() prevGas = gaspool.Gas()
) )
receipt, err := core.ApplyTransactionWithEVM(msg, gaspool, statedb, vmContext.BlockNumber, blockHash, pre.Env.Timestamp, tx, &gasUsed, evm) if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil {
evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
}
// (ret []byte, usedGas uint64, failed bool, err error)
msgResult, err := core.ApplyMessage(evm, msg, gaspool)
if err != nil { if err != nil {
statedb.RevertToSnapshot(snapshot) statedb.RevertToSnapshot(snapshot)
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err) log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
gaspool.SetGas(prevGas) gaspool.SetGas(prevGas)
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil {
evm.Config.Tracer.OnTxEnd(nil, err)
}
continue continue
} }
if receipt.Logs == nil {
receipt.Logs = []*types.Log{}
}
includedTxs = append(includedTxs, tx) includedTxs = append(includedTxs, tx)
if hashError != nil { if hashError != nil {
return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError) return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError)
} }
blobGasUsed += txBlobGas blobGasUsed += txBlobGas
receipts = append(receipts, receipt) gasUsed += msgResult.UsedGas
// Receipt:
{
var root []byte
if chainConfig.IsByzantium(vmContext.BlockNumber) {
statedb.Finalise(true)
} else {
root = statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes()
}
// Create a new receipt for the transaction, storing the intermediate root and
// gas used by the tx.
receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: gasUsed}
if msgResult.Failed() {
receipt.Status = types.ReceiptStatusFailed
} else {
receipt.Status = types.ReceiptStatusSuccessful
}
receipt.TxHash = tx.Hash()
receipt.GasUsed = msgResult.UsedGas
// If the transaction created a contract, store the creation address in the receipt.
if msg.To == nil {
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
}
// Set the receipt logs and create the bloom filter.
receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash, vmContext.Time)
receipt.Bloom = types.CreateBloom(receipt)
// These three are non-consensus fields:
//receipt.BlockHash
//receipt.BlockNumber
receipt.TransactionIndex = uint(txIndex)
receipts = append(receipts, receipt)
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil {
evm.Config.Tracer.OnTxEnd(receipt, nil)
}
}
txIndex++
} }
statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)) statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber))
// Add mining reward? (-1 means rewards are disabled) // Add mining reward? (-1 means rewards are disabled)
if miningReward >= 0 { if miningReward >= 0 {
// Add mining reward. The mining reward may be `0`, which only makes a difference in the cases // Add mining reward. The mining reward may be `0`, which only makes a difference in the cases
@ -310,10 +348,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
// Amount is in gwei, turn into wei // Amount is in gwei, turn into wei
amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei)) amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei))
statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal) statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal)
if isEIP4762 {
statedb.AccessEvents().AddAccount(w.Address, true, stdmath.MaxUint64)
}
} }
// Gather the execution-layer triggered requests. // Gather the execution-layer triggered requests.
@ -374,7 +408,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
execRs.Requests = requests execRs.Requests = requests
} }
// Re-create statedb instance with new root for MPT mode // Re-create statedb instance with new root upon the updated database
// for accessing latest states.
statedb, err = state.New(root, statedb.Database()) 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))
@ -383,20 +418,12 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
return statedb, execRs, body, nil return statedb, execRs, body, nil
} }
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB { func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsVerkle: isBintrie}) tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
sdb := state.NewDatabase(tdb, nil) sdb := state.NewDatabase(tdb, nil)
statedb, _ := state.New(types.EmptyRootHash, sdb)
root := types.EmptyRootHash
if isBintrie {
root = types.EmptyBinaryHash
}
statedb, err := state.New(root, sdb)
if err != nil {
panic(fmt.Errorf("failed to create initial statedb: %v", err))
}
for addr, a := range accounts { for addr, a := range accounts {
statedb.SetCode(addr, a.Code, tracing.CodeChangeUnspecified) statedb.SetCode(addr, a.Code)
statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis) statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis)
statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance) statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance)
for k, v := range a.Storage { for k, v := range a.Storage {
@ -404,24 +431,13 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool
} }
} }
// Commit and re-open to start with a clean state. // Commit and re-open to start with a clean state.
root, err = statedb.Commit(0, false, false) root, _ := statedb.Commit(0, false, false)
if err != nil { statedb, _ = state.New(root, sdb)
panic(fmt.Errorf("failed to commit initial state: %v", err))
}
// If bintrie mode started, check if conversion happened
if isBintrie {
return statedb
}
// For MPT mode, reopen the state with the committed root
statedb, err = state.New(root, sdb)
if err != nil {
panic(fmt.Errorf("failed to reopen state after commit: %v", err))
}
return statedb return statedb
} }
func rlpHash(x any) (h common.Hash) { func rlpHash(x interface{}) (h common.Hash) {
hw := keccak.NewLegacyKeccak256() hw := sha3.NewLegacyKeccak256()
rlp.Encode(hw, x) rlp.Encode(hw, x)
hw.Sum(h[:0]) hw.Sum(h[:0])
return h return h

View file

@ -56,35 +56,27 @@ func (l *fileWritingTracer) Write(p []byte) (n int, err error) {
return n, nil return n, nil
} }
// newFileWriter creates a tracer which wraps inner hooks (typically a logger), // newFileWriter creates a set of hooks which wraps inner hooks (typically a logger),
// and writes the output to a file, one file per transaction. // and writes the output to a file, one file per transaction.
func newFileWriter(baseDir string, innerFn func(out io.Writer) *tracing.Hooks) *tracers.Tracer { func newFileWriter(baseDir string, innerFn func(out io.Writer) *tracing.Hooks) *tracing.Hooks {
t := &fileWritingTracer{ t := &fileWritingTracer{
baseDir: baseDir, baseDir: baseDir,
suffix: "jsonl", suffix: "jsonl",
} }
t.inner = innerFn(t) // instantiate the inner tracer t.inner = innerFn(t) // instantiate the inner tracer
return &tracers.Tracer{ return t.hooks()
Hooks: t.hooks(),
GetResult: func() (json.RawMessage, error) { return json.RawMessage("{}"), nil },
Stop: func(err error) {},
}
} }
// newResultWriter creates a tracer that wraps and invokes an underlying tracer, // newResultWriter creates a set of hooks wraps and invokes an underlying tracer,
// and writes the result (getResult-output) to file, one per transaction. // and writes the result (getResult-output) to file, one per transaction.
func newResultWriter(baseDir string, tracer *tracers.Tracer) *tracers.Tracer { func newResultWriter(baseDir string, tracer *tracers.Tracer) *tracing.Hooks {
t := &fileWritingTracer{ t := &fileWritingTracer{
baseDir: baseDir, baseDir: baseDir,
getResult: tracer.GetResult, getResult: tracer.GetResult,
inner: tracer.Hooks, inner: tracer.Hooks,
suffix: "json", suffix: "json",
} }
return &tracers.Tracer{ return t.hooks()
Hooks: t.hooks(),
GetResult: func() (json.RawMessage, error) { return json.RawMessage("{}"), nil },
Stop: func(err error) {},
}
} }
// OnTxStart creates a new output-file specific for this transaction, and invokes // OnTxStart creates a new output-file specific for this transaction, and invokes

View file

@ -88,14 +88,6 @@ var (
"\t<file> - into the file <file> ", "\t<file> - into the file <file> ",
Value: "block.json", Value: "block.json",
} }
OutputBTFlag = &cli.StringFlag{
Name: "output.vkt",
Usage: "Determines where to put the `BT` of the post-state.\n" +
"\t`stdout` - into the stdout output\n" +
"\t`stderr` - into the stderr output\n" +
"\t<file> - into the file <file> ",
Value: "vkt.json",
}
InputAllocFlag = &cli.StringFlag{ InputAllocFlag = &cli.StringFlag{
Name: "input.alloc", Name: "input.alloc",
Usage: "`stdin` or file name of where to find the prestate alloc to use.", Usage: "`stdin` or file name of where to find the prestate alloc to use.",
@ -131,11 +123,6 @@ var (
Usage: "`stdin` or file name of where to find the transactions list in RLP form.", Usage: "`stdin` or file name of where to find the transactions list in RLP form.",
Value: "txs.rlp", Value: "txs.rlp",
} }
// TODO(@CPerezz): rename `Name` of the file in a follow-up PR (relays on EEST -> https://github.com/ethereum/execution-spec-tests/tree/verkle/main)
InputBTFlag = &cli.StringFlag{
Name: "input.vkt",
Usage: "`stdin` or file name of where to find the prestate BT.",
}
SealCliqueFlag = &cli.StringFlag{ SealCliqueFlag = &cli.StringFlag{
Name: "seal.clique", Name: "seal.clique",
Usage: "Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.", Usage: "Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.",
@ -162,11 +149,6 @@ var (
strings.Join(vm.ActivateableEips(), ", ")), strings.Join(vm.ActivateableEips(), ", ")),
Value: "GrayGlacier", Value: "GrayGlacier",
} }
OpcodeCountFlag = &cli.StringFlag{
Name: "opcode.count",
Usage: "If set, opcode execution counts will be written to this file (relative to output.basedir).",
Value: "",
}
VerbosityFlag = &cli.IntFlag{ VerbosityFlag = &cli.IntFlag{
Name: "verbosity", Name: "verbosity",
Usage: "sets the verbosity level", Usage: "sets the verbosity level",

View file

@ -38,7 +38,6 @@ func (h header) MarshalJSON() ([]byte, error) {
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"` BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"`
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
SlotNumber *math.HexOrDecimal64 `json:"slotNumber" rlp:"optional"`
} }
var enc header var enc header
enc.ParentHash = h.ParentHash enc.ParentHash = h.ParentHash
@ -61,7 +60,6 @@ func (h header) MarshalJSON() ([]byte, error) {
enc.BlobGasUsed = (*math.HexOrDecimal64)(h.BlobGasUsed) enc.BlobGasUsed = (*math.HexOrDecimal64)(h.BlobGasUsed)
enc.ExcessBlobGas = (*math.HexOrDecimal64)(h.ExcessBlobGas) enc.ExcessBlobGas = (*math.HexOrDecimal64)(h.ExcessBlobGas)
enc.ParentBeaconBlockRoot = h.ParentBeaconBlockRoot enc.ParentBeaconBlockRoot = h.ParentBeaconBlockRoot
enc.SlotNumber = (*math.HexOrDecimal64)(h.SlotNumber)
return json.Marshal(&enc) return json.Marshal(&enc)
} }
@ -88,7 +86,6 @@ func (h *header) UnmarshalJSON(input []byte) error {
BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"` BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed" rlp:"optional"`
ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"` ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas" rlp:"optional"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"`
SlotNumber *math.HexOrDecimal64 `json:"slotNumber" rlp:"optional"`
} }
var dec header var dec header
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
@ -158,8 +155,5 @@ func (h *header) UnmarshalJSON(input []byte) error {
if dec.ParentBeaconBlockRoot != nil { if dec.ParentBeaconBlockRoot != nil {
h.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot h.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
} }
if dec.SlotNumber != nil {
h.SlotNumber = (*uint64)(dec.SlotNumber)
}
return nil return nil
} }

View file

@ -37,7 +37,6 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"` ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"` ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *math.HexOrDecimal64 `json:"slotNumber"`
} }
var enc stEnv var enc stEnv
enc.Coinbase = common.UnprefixedAddress(s.Coinbase) enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
@ -60,7 +59,6 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas) enc.ParentExcessBlobGas = (*math.HexOrDecimal64)(s.ParentExcessBlobGas)
enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed) enc.ParentBlobGasUsed = (*math.HexOrDecimal64)(s.ParentBlobGasUsed)
enc.ParentBeaconBlockRoot = s.ParentBeaconBlockRoot enc.ParentBeaconBlockRoot = s.ParentBeaconBlockRoot
enc.SlotNumber = (*math.HexOrDecimal64)(s.SlotNumber)
return json.Marshal(&enc) return json.Marshal(&enc)
} }
@ -87,7 +85,6 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"` ParentExcessBlobGas *math.HexOrDecimal64 `json:"parentExcessBlobGas,omitempty"`
ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"` ParentBlobGasUsed *math.HexOrDecimal64 `json:"parentBlobGasUsed,omitempty"`
ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"` ParentBeaconBlockRoot *common.Hash `json:"parentBeaconBlockRoot"`
SlotNumber *math.HexOrDecimal64 `json:"slotNumber"`
} }
var dec stEnv var dec stEnv
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
@ -157,8 +154,5 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
if dec.ParentBeaconBlockRoot != nil { if dec.ParentBeaconBlockRoot != nil {
s.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot s.ParentBeaconBlockRoot = dec.ParentBeaconBlockRoot
} }
if dec.SlotNumber != nil {
s.SlotNumber = (*uint64)(dec.SlotNumber)
}
return nil return nil
} }

View file

@ -115,6 +115,9 @@ func Transaction(ctx *cli.Context) error {
} }
var results []result var results []result
for it.Next() { for it.Next() {
if err := it.Err(); err != nil {
return NewError(ErrorIO, err)
}
var tx types.Transaction var tx types.Transaction
err := rlp.DecodeBytes(it.Value(), &tx) err := rlp.DecodeBytes(it.Value(), &tx)
if err != nil { if err != nil {
@ -185,10 +188,6 @@ func Transaction(ctx *cli.Context) error {
} }
results = append(results, r) results = append(results, r)
} }
if err := it.Err(); err != nil {
return NewError(ErrorIO, err)
}
out, err := json.MarshalIndent(results, "", " ") out, err := json.MarshalIndent(results, "", " ")
fmt.Println(string(out)) fmt.Println(string(out))
return err return err

View file

@ -28,23 +28,15 @@ 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/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"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/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/eth/tracers/native"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/tests" "github.com/ethereum/go-ethereum/tests"
"github.com/ethereum/go-ethereum/trie/bintrie"
"github.com/ethereum/go-ethereum/triedb"
"github.com/ethereum/go-ethereum/triedb/database"
"github.com/holiman/uint256"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
@ -83,11 +75,10 @@ var (
) )
type input struct { type input struct {
Alloc types.GenesisAlloc `json:"alloc,omitempty"` Alloc types.GenesisAlloc `json:"alloc,omitempty"`
Env *stEnv `json:"env,omitempty"` Env *stEnv `json:"env,omitempty"`
BT map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"` Txs []*txWithKey `json:"txs,omitempty"`
Txs []*txWithKey `json:"txs,omitempty"` TxRlp string `json:"txsRlp,omitempty"`
TxRlp string `json:"txsRlp,omitempty"`
} }
func Transition(ctx *cli.Context) error { func Transition(ctx *cli.Context) error {
@ -99,16 +90,16 @@ func Transition(ctx *cli.Context) error {
// stdin input or in files. // stdin input or in files.
// Check if anything needs to be read from stdin // Check if anything needs to be read from stdin
var ( var (
prestate Prestate prestate Prestate
txIt txIterator // txs to apply txIt txIterator // txs to apply
allocStr = ctx.String(InputAllocFlag.Name) allocStr = ctx.String(InputAllocFlag.Name)
btStr = ctx.String(InputBTFlag.Name)
envStr = ctx.String(InputEnvFlag.Name) envStr = ctx.String(InputEnvFlag.Name)
txStr = ctx.String(InputTxsFlag.Name) txStr = ctx.String(InputTxsFlag.Name)
inputData = &input{} inputData = &input{}
) )
// Figure out the prestate alloc // Figure out the prestate alloc
if allocStr == stdinSelector || btStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector { if allocStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector {
decoder := json.NewDecoder(os.Stdin) decoder := json.NewDecoder(os.Stdin)
if err := decoder.Decode(inputData); err != nil { if err := decoder.Decode(inputData); err != nil {
return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err)) return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err))
@ -121,13 +112,6 @@ func Transition(ctx *cli.Context) error {
} }
prestate.Pre = inputData.Alloc prestate.Pre = inputData.Alloc
if btStr != stdinSelector && btStr != "" {
if err := readFile(btStr, "BT", &inputData.BT); err != nil {
return err
}
}
prestate.TreeLeaves = inputData.BT
// Set the block environment // Set the block environment
if envStr != stdinSelector { if envStr != stdinSelector {
var env stEnv var env stEnv
@ -168,15 +152,14 @@ func Transition(ctx *cli.Context) error {
} }
// Configure tracer // Configure tracer
var tracer *tracers.Tracer
if ctx.IsSet(TraceTracerFlag.Name) { // Custom tracing if ctx.IsSet(TraceTracerFlag.Name) { // Custom tracing
config := json.RawMessage(ctx.String(TraceTracerConfigFlag.Name)) config := json.RawMessage(ctx.String(TraceTracerConfigFlag.Name))
innerTracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name), tracer, err := tracers.DefaultDirectory.New(ctx.String(TraceTracerFlag.Name),
nil, config, chainConfig) nil, config, chainConfig)
if err != nil { if err != nil {
return NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %v", err)) return NewError(ErrorConfig, fmt.Errorf("failed instantiating tracer: %v", err))
} }
tracer = newResultWriter(baseDir, innerTracer) vmConfig.Tracer = newResultWriter(baseDir, tracer)
} else if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing } else if ctx.Bool(TraceFlag.Name) { // JSON opcode tracing
logConfig := &logger.Config{ logConfig := &logger.Config{
DisableStack: ctx.Bool(TraceDisableStackFlag.Name), DisableStack: ctx.Bool(TraceDisableStackFlag.Name),
@ -184,61 +167,24 @@ func Transition(ctx *cli.Context) error {
EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name), EnableReturnData: ctx.Bool(TraceEnableReturnDataFlag.Name),
} }
if ctx.Bool(TraceEnableCallFramesFlag.Name) { if ctx.Bool(TraceEnableCallFramesFlag.Name) {
tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks { vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks {
return logger.NewJSONLoggerWithCallFrames(logConfig, out) return logger.NewJSONLoggerWithCallFrames(logConfig, out)
}) })
} else { } else {
tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks { vmConfig.Tracer = newFileWriter(baseDir, func(out io.Writer) *tracing.Hooks {
return logger.NewJSONLogger(logConfig, out) return logger.NewJSONLogger(logConfig, out)
}) })
} }
} }
// Configure opcode counter
var opcodeTracer *tracers.Tracer
if ctx.IsSet(OpcodeCountFlag.Name) && ctx.String(OpcodeCountFlag.Name) != "" {
opcodeTracer = native.NewOpcodeCounter()
if tracer != nil {
// If we have an existing tracer, multiplex with the opcode tracer
mux, _ := native.NewMuxTracer([]string{"trace", "opcode"}, []*tracers.Tracer{tracer, opcodeTracer})
vmConfig.Tracer = mux.Hooks
} else {
vmConfig.Tracer = opcodeTracer.Hooks
}
} else if tracer != nil {
vmConfig.Tracer = tracer.Hooks
}
// Run the test and aggregate the result // Run the test and aggregate the result
s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name)) s, result, body, err := prestate.Apply(vmConfig, chainConfig, txIt, ctx.Int64(RewardFlag.Name))
if err != nil { if err != nil {
return err return err
} }
// Write opcode counts if enabled
if opcodeTracer != nil {
fname := ctx.String(OpcodeCountFlag.Name)
result, err := opcodeTracer.GetResult()
if err != nil {
return NewError(ErrorJson, fmt.Errorf("failed getting opcode counts: %v", err))
}
if err := saveFile(baseDir, fname, result); err != nil {
return err
}
}
// Dump the execution result // Dump the execution result
var ( collector := make(Alloc)
collector = make(Alloc) s.DumpToCollector(collector, nil)
btleaves map[common.Hash]hexutil.Bytes return dispatchOutput(ctx, baseDir, result, collector, body)
)
isBinary := chainConfig.IsVerkle(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
if !isBinary {
s.DumpToCollector(collector, nil)
} else {
btleaves = make(map[common.Hash]hexutil.Bytes)
if err := s.DumpBinTrieLeaves(btleaves); err != nil {
return err
}
}
return dispatchOutput(ctx, baseDir, result, collector, body, btleaves)
} }
func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
@ -360,7 +306,7 @@ func saveFile(baseDir, filename string, data interface{}) error {
// dispatchOutput writes the output data to either stderr or stdout, or to the specified // dispatchOutput writes the output data to either stderr or stdout, or to the specified
// files // files
func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes, bt map[common.Hash]hexutil.Bytes) error { func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes) error {
stdOutObject := make(map[string]interface{}) stdOutObject := make(map[string]interface{})
stdErrObject := make(map[string]interface{}) stdErrObject := make(map[string]interface{})
dispatch := func(baseDir, fName, name string, obj interface{}) error { dispatch := func(baseDir, fName, name string, obj interface{}) error {
@ -387,13 +333,6 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
if err := dispatch(baseDir, ctx.String(OutputBodyFlag.Name), "body", body); err != nil { if err := dispatch(baseDir, ctx.String(OutputBodyFlag.Name), "body", body); err != nil {
return err return err
} }
// Only write bt output if we actually have binary trie leaves
if bt != nil {
if err := dispatch(baseDir, ctx.String(OutputBTFlag.Name), "vkt", bt); err != nil {
return err
}
}
if len(stdOutObject) > 0 { if len(stdOutObject) > 0 {
b, err := json.MarshalIndent(stdOutObject, "", " ") b, err := json.MarshalIndent(stdOutObject, "", " ")
if err != nil { if err != nil {
@ -412,168 +351,3 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a
} }
return nil return nil
} }
// BinKey computes the tree key given an address and an optional slot number.
func BinKey(ctx *cli.Context) error {
if ctx.Args().Len() == 0 || ctx.Args().Len() > 2 {
return errors.New("invalid number of arguments: expecting an address and an optional slot number")
}
addr, err := hexutil.Decode(ctx.Args().Get(0))
if err != nil {
return fmt.Errorf("error decoding address: %w", err)
}
if ctx.Args().Len() == 2 {
slot, err := hexutil.Decode(ctx.Args().Get(1))
if err != nil {
return fmt.Errorf("error decoding slot: %w", err)
}
fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyStorageSlot(common.BytesToAddress(addr), slot))
} else {
fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyBasicData(common.BytesToAddress(addr)))
}
return nil
}
// BinKeys computes a set of tree keys given a genesis alloc.
func BinKeys(ctx *cli.Context) error {
var allocStr = ctx.String(InputAllocFlag.Name)
var alloc core.GenesisAlloc
// Figure out the prestate alloc
if allocStr == stdinSelector {
decoder := json.NewDecoder(os.Stdin)
if err := decoder.Decode(&alloc); err != nil {
return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err))
}
}
if allocStr != stdinSelector {
if err := readFile(allocStr, "alloc", &alloc); err != nil {
return err
}
}
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults)
defer db.Close()
bt, err := genBinTrieFromAlloc(alloc, db)
if err != nil {
return fmt.Errorf("error generating bt: %w", err)
}
collector := make(map[common.Hash]hexutil.Bytes)
it, err := bt.NodeIterator(nil)
if err != nil {
panic(err)
}
for it.Next(true) {
if it.Leaf() {
collector[common.BytesToHash(it.LeafKey())] = it.LeafBlob()
}
}
output, err := json.MarshalIndent(collector, "", "")
if err != nil {
return fmt.Errorf("error outputting tree: %w", err)
}
fmt.Println(string(output))
return nil
}
// BinTrieRoot computes the root of a Binary Trie from a genesis alloc.
func BinTrieRoot(ctx *cli.Context) error {
var allocStr = ctx.String(InputAllocFlag.Name)
var alloc core.GenesisAlloc
if allocStr == stdinSelector {
decoder := json.NewDecoder(os.Stdin)
if err := decoder.Decode(&alloc); err != nil {
return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err))
}
}
if allocStr != stdinSelector {
if err := readFile(allocStr, "alloc", &alloc); err != nil {
return err
}
}
db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults)
defer db.Close()
bt, err := genBinTrieFromAlloc(alloc, db)
if err != nil {
return fmt.Errorf("error generating bt: %w", err)
}
fmt.Println(bt.Hash().Hex())
return nil
}
// TODO(@CPerezz): Should this go to `bintrie` module?
func genBinTrieFromAlloc(alloc core.GenesisAlloc, db database.NodeDatabase) (*bintrie.BinaryTrie, error) {
bt, err := bintrie.NewBinaryTrie(types.EmptyBinaryHash, db)
if err != nil {
return nil, err
}
for addr, acc := range alloc {
for slot, value := range acc.Storage {
err := bt.UpdateStorage(addr, slot.Bytes(), value.Big().Bytes())
if err != nil {
return nil, fmt.Errorf("error inserting storage: %w", err)
}
}
account := &types.StateAccount{
Balance: uint256.MustFromBig(acc.Balance),
Nonce: acc.Nonce,
CodeHash: crypto.Keccak256Hash(acc.Code).Bytes(),
Root: common.Hash{},
}
err := bt.UpdateAccount(addr, account, len(acc.Code))
if err != nil {
return nil, fmt.Errorf("error inserting account: %w", err)
}
err = bt.UpdateContractCode(addr, common.BytesToHash(account.CodeHash), acc.Code)
if err != nil {
return nil, fmt.Errorf("error inserting code: %w", err)
}
}
return bt, nil
}
// BinaryCodeChunkKey computes the tree key of a code-chunk for a given address.
func BinaryCodeChunkKey(ctx *cli.Context) error {
if ctx.Args().Len() == 0 || ctx.Args().Len() > 2 {
return errors.New("invalid number of arguments: expecting an address and an code-chunk number")
}
addr, err := hexutil.Decode(ctx.Args().Get(0))
if err != nil {
return fmt.Errorf("error decoding address: %w", err)
}
chunkNumberBytes, err := hexutil.Decode(ctx.Args().Get(1))
if err != nil {
return fmt.Errorf("error decoding chunk number: %w", err)
}
var chunkNumber uint256.Int
chunkNumber.SetBytes(chunkNumberBytes)
fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyCodeChunk(common.BytesToAddress(addr), &chunkNumber))
return nil
}
// BinaryCodeChunkCode returns the code chunkification for a given code.
func BinaryCodeChunkCode(ctx *cli.Context) error {
if ctx.Args().Len() == 0 || ctx.Args().Len() > 1 {
return errors.New("invalid number of arguments: expecting a bytecode")
}
bytecode, err := hexutil.Decode(ctx.Args().Get(0))
if err != nil {
return fmt.Errorf("error decoding address: %w", err)
}
chunkedCode := bintrie.ChunkifyCode(bytecode)
fmt.Printf("%#x\n", chunkedCode)
return nil
}

View file

@ -55,11 +55,6 @@ var (
Usage: "benchmark the execution", Usage: "benchmark the execution",
Category: flags.VMCategory, Category: flags.VMCategory,
} }
FuzzFlag = &cli.BoolFlag{
Name: "fuzz",
Usage: "adapts output format for fuzzing",
Category: flags.VMCategory,
}
WitnessCrossCheckFlag = &cli.BoolFlag{ WitnessCrossCheckFlag = &cli.BoolFlag{
Name: "cross-check", Name: "cross-check",
Aliases: []string{"xc"}, Aliases: []string{"xc"},
@ -151,64 +146,16 @@ var (
t8ntool.TraceEnableCallFramesFlag, t8ntool.TraceEnableCallFramesFlag,
t8ntool.OutputBasedir, t8ntool.OutputBasedir,
t8ntool.OutputAllocFlag, t8ntool.OutputAllocFlag,
t8ntool.OutputBTFlag,
t8ntool.OutputResultFlag, t8ntool.OutputResultFlag,
t8ntool.OutputBodyFlag, t8ntool.OutputBodyFlag,
t8ntool.InputAllocFlag, t8ntool.InputAllocFlag,
t8ntool.InputEnvFlag, t8ntool.InputEnvFlag,
t8ntool.InputBTFlag,
t8ntool.InputTxsFlag, t8ntool.InputTxsFlag,
t8ntool.ForknameFlag, t8ntool.ForknameFlag,
t8ntool.ChainIDFlag, t8ntool.ChainIDFlag,
t8ntool.RewardFlag, t8ntool.RewardFlag,
t8ntool.OpcodeCountFlag,
}, },
} }
verkleCommand = &cli.Command{
Name: "verkle",
Aliases: []string{"vkt"},
Usage: "Binary Trie helpers",
Subcommands: []*cli.Command{
{
Name: "tree-keys",
Aliases: []string{"v"},
Usage: "compute a set of binary trie keys, given their source addresses and optional slot numbers",
Action: t8ntool.BinKeys,
Flags: []cli.Flag{
t8ntool.InputAllocFlag,
},
},
{
Name: "single-key",
Aliases: []string{"vk"},
Usage: "compute the binary trie key given an address and optional slot number",
Action: t8ntool.BinKey,
},
{
Name: "code-chunk-key",
Aliases: []string{"vck"},
Usage: "compute the binary trie key given an address and chunk number",
Action: t8ntool.BinaryCodeChunkKey,
},
{
Name: "chunkify-code",
Aliases: []string{"vcc"},
Usage: "chunkify a given bytecode for a binary trie",
Action: t8ntool.BinaryCodeChunkCode,
},
{
Name: "state-root",
Aliases: []string{"vsr"},
Usage: "compute the state-root of a binary trie for the given alloc",
Action: t8ntool.BinTrieRoot,
Flags: []cli.Flag{
t8ntool.InputAllocFlag,
},
},
},
}
transactionCommand = &cli.Command{ transactionCommand = &cli.Command{
Name: "transaction", Name: "transaction",
Aliases: []string{"t9n"}, Aliases: []string{"t9n"},
@ -263,7 +210,6 @@ func init() {
stateTransitionCommand, stateTransitionCommand,
transactionCommand, transactionCommand,
blockBuilderCommand, blockBuilderCommand,
verkleCommand,
} }
app.Before = func(ctx *cli.Context) error { app.Before = func(ctx *cli.Context) error {
flags.MigrateGlobalFlags(ctx) flags.MigrateGlobalFlags(ctx)

View file

@ -322,7 +322,7 @@ func runCmd(ctx *cli.Context) error {
} }
} else { } else {
if len(code) > 0 { if len(code) > 0 {
prestate.SetCode(receiver, code, tracing.CodeChangeUnspecified) prestate.SetCode(receiver, code)
} }
execFunc = func() ([]byte, uint64, error) { execFunc = func() ([]byte, uint64, error) {
// don't mutate the state! // don't mutate the state!

View file

@ -296,14 +296,6 @@ func TestT8n(t *testing.T) {
output: t8nOutput{alloc: true, result: true}, output: t8nOutput{alloc: true, result: true},
expOut: "exp.json", expOut: "exp.json",
}, },
{ // Osaka test, EIP-7918 blob gas with parent base fee
base: "./testdata/34",
input: t8nInput{
"alloc.json", "txs.json", "env.json", "Osaka", "",
},
output: t8nOutput{alloc: true, result: true},
expOut: "exp.json",
},
} { } {
args := []string{"t8n"} args := []string{"t8n"}
args = append(args, tc.output.get()...) args = append(args, tc.output.get()...)

View file

@ -24,13 +24,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x5208", "cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673", "transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208", "gasUsed": "0x5208",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -12,13 +12,12 @@
"status": "0x0", "status": "0x0",
"cumulativeGasUsed": "0x84d0", "cumulativeGasUsed": "0x84d0",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476", "transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x84d0", "gasUsed": "0x84d0",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
}, },
{ {
@ -27,13 +26,12 @@
"status": "0x0", "status": "0x0",
"cumulativeGasUsed": "0x109a0", "cumulativeGasUsed": "0x109a0",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a", "transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x84d0", "gasUsed": "0x84d0",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x1" "transactionIndex": "0x1"
} }
], ],

View file

@ -11,13 +11,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x520b", "cumulativeGasUsed": "0x520b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81", "transactionHash": "0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x520b", "gasUsed": "0x520b",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x5",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -27,13 +27,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0xa861", "cumulativeGasUsed": "0xa861",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941", "transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0xa861", "gasUsed": "0xa861",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
}, },
{ {
@ -41,13 +40,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x10306", "cumulativeGasUsed": "0x10306",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x16b1d912f1d664f3f60f4e1b5f296f3c82a64a1a253117b4851d18bc03c4f1da", "transactionHash": "0x16b1d912f1d664f3f60f4e1b5f296f3c82a64a1a253117b4851d18bc03c4f1da",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5aa5", "gasUsed": "0x5aa5",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x1" "transactionIndex": "0x1"
} }
], ],

View file

@ -23,13 +23,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x5208", "cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941", "transactionHash": "0x92ea4a28224d033afb20e0cc2b290d4c7c2d61f6a4800a680e4e19ac962ee941",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208", "gasUsed": "0x5208",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -28,15 +28,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0xa865", "cumulativeGasUsed": "0xa865",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x7508d7139d002a4b3a26a4f12dec0d87cb46075c78bf77a38b569a133b509262", "transactionHash": "0x7508d7139d002a4b3a26a4f12dec0d87cb46075c78bf77a38b569a133b509262",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0xa865", "gasUsed": "0xa865",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blobGasUsed": "0x20000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blobGasPrice": "0x1",
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -26,13 +26,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x5208", "cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x84f70aba406a55628a0620f26d260f90aeb6ccc55fed6ec2ac13dd4f727032ed", "transactionHash": "0x84f70aba406a55628a0620f26d260f90aeb6ccc55fed6ec2ac13dd4f727032ed",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208", "gasUsed": "0x5208",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -24,13 +24,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x521f", "cumulativeGasUsed": "0x521f",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81", "transactionHash": "0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x521f", "gasUsed": "0x521f",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x5",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

View file

@ -25,13 +25,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x5208", "cumulativeGasUsed": "0x5208",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476", "transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208", "gasUsed": "0x5208",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
}, },
{ {
@ -40,13 +39,12 @@
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0xa410", "cumulativeGasUsed": "0xa410",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"logs": [], "logs": null,
"transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a", "transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x5208", "gasUsed": "0x5208",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x1" "transactionIndex": "0x1"
} }
], ],

View file

@ -44,12 +44,11 @@
"root": "0x", "root": "0x",
"status": "0x1", "status": "0x1",
"cumulativeGasUsed": "0x15fa9", "cumulativeGasUsed": "0x15fa9",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","logs": [],"transactionHash": "0x0417aab7c1d8a3989190c3167c132876ce9b8afd99262c5a0f9d06802de3d7ef", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","logs": null,"transactionHash": "0x0417aab7c1d8a3989190c3167c132876ce9b8afd99262c5a0f9d06802de3d7ef",
"contractAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x0000000000000000000000000000000000000000",
"gasUsed": "0x15fa9", "gasUsed": "0x15fa9",
"effectiveGasPrice": null, "effectiveGasPrice": null,
"blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x1",
"transactionIndex": "0x0" "transactionIndex": "0x0"
} }
], ],

Some files were not shown because too many files have changed in this diff Show more