mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-01 17:13:45 +00:00
Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d818a9af7b |
614 changed files with 25250 additions and 60198 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
47
.github/workflows/go.yml
vendored
47
.github/workflows/go.yml
vendored
|
|
@ -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:
|
||||||
|
|
@ -34,51 +34,10 @@ 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:
|
||||||
|
|
@ -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 ./...
|
||||||
|
|
|
||||||
62
.github/workflows/validate_pr.yml
vendored
62
.github/workflows/validate_pr.yml
vendored
|
|
@ -8,76 +8,16 @@ jobs:
|
||||||
validate-pr:
|
validate-pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
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
|
- name: Check PR Title Format
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const prTitle = context.payload.pull_request.title;
|
const prTitle = context.payload.pull_request.title;
|
||||||
const titleRegex = /^([\w\s,{}/.]+): .+/;
|
const titleRegex = /^(\.?[\w\s,{}/]+): .+/;
|
||||||
|
|
||||||
if (!titleRegex.test(prTitle)) {
|
if (!titleRegex.test(prTitle)) {
|
||||||
core.setFailed(`PR title "${prTitle}" does not match required format: directory, ...: description`);
|
core.setFailed(`PR title "${prTitle}" does not match required format: directory, ...: description`);
|
||||||
return;
|
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');
|
console.log('✅ PR title format is valid');
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -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
|
|
||||||
|
|
|
||||||
98
AGENTS.md
98
AGENTS.md
|
|
@ -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.
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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{}{}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
20
appveyor.yml
20
appveyor.yml
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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{})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
|
|
|
||||||
|
|
@ -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[:]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0xbb7a7f3c40d8ea0b450f91587db65d0f1c079669277e01a0426c8911702a863a
|
0x1bbf958008172591b6cbdb3d8d52e26998258e83d4bdb9eec10969d84519a6bd
|
||||||
|
|
@ -1 +1 @@
|
||||||
0x2af778d703186526a1b6304b423f338f11556206f618643c3f7fa0d7b1ef5c9b
|
0x2fe39a39b6f7cbd549e0f74d259de6db486005a65bd3bd92840dd6ce21d6f4c8
|
||||||
|
|
@ -1 +1 @@
|
||||||
0x48a89c9ea7ba19de2931797974cf8722344ab231c0edada278b108ef74125478
|
0x86686b2b366e24134e0e3969a9c5f3759f92e5d2b04785b42e22cc7d468c2107
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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"))
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.25.0
|
||||||
# https://go.dev/dl/
|
# https://go.dev/dl/
|
||||||
178f2832820274b43e177d32f06a3ebb0129e427dd20a5e4c88df2c1763cf10a go1.25.7.src.tar.gz
|
4bd01e91297207bfa450ea40d4d5a93b1b531a5e438473b2a06e18e077227225 go1.25.0.src.tar.gz
|
||||||
81bf2a1f20633f62d55d826d82dde3b0570cf1408a91e15781b266037299285b go1.25.7.aix-ppc64.tar.gz
|
e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4 go1.25.0.aix-ppc64.tar.gz
|
||||||
bf5050a2152f4053837b886e8d9640c829dbacbc3370f913351eb0904cb706f5 go1.25.7.darwin-amd64.tar.gz
|
5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef go1.25.0.darwin-amd64.tar.gz
|
||||||
ff18369ffad05c57d5bed888b660b31385f3c913670a83ef557cdfd98ea9ae1b go1.25.7.darwin-arm64.tar.gz
|
95e836238bcf8f9a71bffea43344cbd35ee1f16db3aaced2f98dbac045d102db go1.25.0.darwin-amd64.pkg
|
||||||
c5dccd7f192dd7b305dc209fb316ac1917776d74bd8e4d532ef2772f305bf42a go1.25.7.dragonfly-amd64.tar.gz
|
544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c go1.25.0.darwin-arm64.tar.gz
|
||||||
a2de97c8ac74bf64b0ae73fe9d379e61af530e061bc7f8f825044172ffe61a8b go1.25.7.freebsd-386.tar.gz
|
202a0d8338c152cb4c9f04782429e9ba8bef31d9889272380837e4043c9d800a go1.25.0.darwin-arm64.pkg
|
||||||
055f9e138787dcafa81eb0314c8ff70c6dd0f6dba1e8a6957fef5d5efd1ab8fd go1.25.7.freebsd-amd64.tar.gz
|
5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120 go1.25.0.dragonfly-amd64.tar.gz
|
||||||
60e7f7a7c990f0b9539ac8ed668155746997d404643a4eecd47b3dee1b7e710b go1.25.7.freebsd-arm.tar.gz
|
abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e go1.25.0.freebsd-386.tar.gz
|
||||||
631e03d5fd4c526e2f499154d8c6bf4cb081afb2fff171c428722afc9539d53a go1.25.7.freebsd-arm64.tar.gz
|
86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b go1.25.0.freebsd-amd64.tar.gz
|
||||||
8a264fd685823808140672812e3ad9c43f6ad59444c0dc14cdd3a1351839ddd5 go1.25.7.freebsd-riscv64.tar.gz
|
d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe go1.25.0.freebsd-arm.tar.gz
|
||||||
57c672447d906a1bcab98f2b11492d54521a791aacbb4994a25169e59cbe289a go1.25.7.illumos-amd64.tar.gz
|
451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e go1.25.0.freebsd-arm64.tar.gz
|
||||||
2866517e9ca81e6a2e85a930e9b11bc8a05cfeb2fc6dc6cb2765e7fb3c14b715 go1.25.7.linux-386.tar.gz
|
7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe go1.25.0.freebsd-riscv64.tar.gz
|
||||||
12e6d6a191091ae27dc31f6efc630e3a3b8ba409baf3573d955b196fdf086005 go1.25.7.linux-amd64.tar.gz
|
b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c go1.25.0.illumos-amd64.tar.gz
|
||||||
ba611a53534135a81067240eff9508cd7e256c560edd5d8c2fef54f083c07129 go1.25.7.linux-arm64.tar.gz
|
8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a go1.25.0.linux-386.tar.gz
|
||||||
1ba07e0eb86b839e72467f4b5c7a5597d07f30bcf5563c951410454f7cda5266 go1.25.7.linux-armv6l.tar.gz
|
2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613 go1.25.0.linux-amd64.tar.gz
|
||||||
775753fc5952a334c415f08768df2f0b73a3228a16e8f5f63d545daacb4e3357 go1.25.7.linux-loong64.tar.gz
|
05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae go1.25.0.linux-arm64.tar.gz
|
||||||
1a023bb367c5fbb4c637a2f6dc23ff17c6591ad929ce16ea88c74d857153b307 go1.25.7.linux-mips.tar.gz
|
a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09 go1.25.0.linux-armv6l.tar.gz
|
||||||
a8e97223d8aa6fdfd45f132a4784d2f536bbac5f3d63a24b63d33b6bfe1549af go1.25.7.linux-mips64.tar.gz
|
cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc go1.25.0.linux-loong64.tar.gz
|
||||||
eb9edb6223330d5e20275667c65dea076b064c08e595fe4eba5d7d6055cfaccf go1.25.7.linux-mips64le.tar.gz
|
d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1 go1.25.0.linux-mips.tar.gz
|
||||||
9c1e693552a5f9bb9e0012d1c5e01456ecefbc59bef53a77305222ce10aba368 go1.25.7.linux-mipsle.tar.gz
|
4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2 go1.25.0.linux-mips64.tar.gz
|
||||||
28a788798e7329acbbc0ac2caa5e4368b1e5ede646cc24429c991214cfb45c63 go1.25.7.linux-ppc64.tar.gz
|
70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc go1.25.0.linux-mips64le.tar.gz
|
||||||
42124c0edc92464e2b37b2d7fcd3658f0c47ebd6a098732415a522be8cb88e3f go1.25.7.linux-ppc64le.tar.gz
|
b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73 go1.25.0.linux-mipsle.tar.gz
|
||||||
88d59c6893c8425875d6eef8e3434bc2fa2552e5ad4c058c6cd8cd710a0301c8 go1.25.7.linux-riscv64.tar.gz
|
df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1 go1.25.0.linux-ppc64.tar.gz
|
||||||
c6b77facf666dc68195ecab05dbf0ebb4e755b2a8b7734c759880557f1c29b0c go1.25.7.linux-s390x.tar.gz
|
0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0 go1.25.0.linux-ppc64le.tar.gz
|
||||||
f14c184d9ade0ee04c7735d4071257b90896ecbde1b32adae84135f055e6399b go1.25.7.netbsd-386.tar.gz
|
c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67 go1.25.0.linux-riscv64.tar.gz
|
||||||
7e7389e404dca1088c31f0fc07f1dd60891d7182bcd621469c14f7e79eceb3ff go1.25.7.netbsd-amd64.tar.gz
|
34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408 go1.25.0.linux-s390x.tar.gz
|
||||||
70388bb3ef2f03dbf1357e9056bd09034a67e018262557354f8cf549766b3f9d go1.25.7.netbsd-arm.tar.gz
|
f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba go1.25.0.netbsd-386.tar.gz
|
||||||
8c1cda9d25bfc9b18d24d5f95fc23949dd3ff99fa408a6cfa40e2cf12b07e362 go1.25.7.netbsd-arm64.tar.gz
|
ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a go1.25.0.netbsd-amd64.tar.gz
|
||||||
42f0d1bfbe39b8401cccb84dd66b30795b97bfc9620dfdc17c5cd4fcf6495cb0 go1.25.7.openbsd-386.tar.gz
|
1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7 go1.25.0.netbsd-arm.tar.gz
|
||||||
e514879c0a28bc32123cd52c4c093de912477fe83f36a6d07517d066ef55391a go1.25.7.openbsd-amd64.tar.gz
|
e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16 go1.25.0.netbsd-arm64.tar.gz
|
||||||
8cd22530695a0218232bf7efea8f162df1697a3106942ac4129b8c3de39ce4ef go1.25.7.openbsd-arm.tar.gz
|
4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8 go1.25.0.openbsd-386.tar.gz
|
||||||
938720f6ebc0d1c53d7840321d3a31f29fd02496e84a6538f442a9311dc1cc9a go1.25.7.openbsd-arm64.tar.gz
|
c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1 go1.25.0.openbsd-amd64.tar.gz
|
||||||
a4c378b73b98f89a3596c2ef51aabbb28783d9ca29f7e317d8ca07939660ce6f go1.25.7.openbsd-ppc64.tar.gz
|
a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d go1.25.0.openbsd-arm.tar.gz
|
||||||
937b58734fbeaa8c7941a0e4285e7e84b7885396e8d11c23f9ab1a8ff10ff20e go1.25.7.openbsd-riscv64.tar.gz
|
343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d go1.25.0.openbsd-arm64.tar.gz
|
||||||
61a093c8c5244916f25740316386bb9f141545dcf01b06a79d1c78ece488403e go1.25.7.plan9-386.tar.gz
|
694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154 go1.25.0.openbsd-ppc64.tar.gz
|
||||||
7fc8f6689c9de8ccb7689d2278035fa83c2d601409101840df6ddfe09ba58699 go1.25.7.plan9-amd64.tar.gz
|
aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f go1.25.0.openbsd-riscv64.tar.gz
|
||||||
9661dff8eaeeb62f1c3aadbc5ff189a2e6744e1ec885e32dbcb438f58a34def5 go1.25.7.plan9-arm.tar.gz
|
46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986 go1.25.0.plan9-386.tar.gz
|
||||||
28ecba0e1d7950c8b29a4a04962dd49c3bf5221f55a44f17d98f369f82859cf4 go1.25.7.solaris-amd64.tar.gz
|
29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b go1.25.0.plan9-amd64.tar.gz
|
||||||
baa6b488291801642fa620026169e38bec2da2ac187cd3ae2145721cf826bbc3 go1.25.7.windows-386.zip
|
0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2 go1.25.0.plan9-arm.tar.gz
|
||||||
c75e5f4ff62d085cc0017be3ad19d5536f46825fa05db06ec468941f847e3228 go1.25.7.windows-amd64.zip
|
9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611 go1.25.0.solaris-amd64.tar.gz
|
||||||
807033f85931bc4a589ca8497535dcbeb1f30d506e47fa200f5f04c4a71c3d9f go1.25.7.windows-arm64.zip
|
df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7 go1.25.0.windows-386.zip
|
||||||
|
afd9e0a8d2665ff122c8302bb4a3ce4a5331e4e630ddc388be1f9238adfa8fe3 go1.25.0.windows-386.msi
|
||||||
|
89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b go1.25.0.windows-amd64.zip
|
||||||
|
936bd87109da515f79d80211de5bc6cbda071f2cc577f7e6af1a9e754ea34819 go1.25.0.windows-amd64.msi
|
||||||
|
27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c go1.25.0.windows-arm64.zip
|
||||||
|
357d030b217ff68e700b6cfc56097bc21ad493bb45b79733a052d112f5031ed9 go1.25.0.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!
|
||||||
#
|
#
|
||||||
|
|
|
||||||
242
build/ci.go
242
build/ci.go
|
|
@ -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,8 @@ 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
|
||||||
|
"plucky", // 25.04, EOL: 01/2026
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is where the tests should be unpacked.
|
// This is where the tests should be unpacked.
|
||||||
|
|
@ -186,7 +143,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 +172,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 +206,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 +216,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 +228,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 +260,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 +283,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 +308,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 +322,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)
|
||||||
|
|
@ -452,51 +351,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 +424,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 +587,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 +859,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,14 +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/>.
|
||||||
|
|
||||||
//go:build !example && !ziren && !wasm
|
//go:build tools
|
||||||
// +build !example,!ziren,!wasm
|
// +build tools
|
||||||
|
|
||||||
package main
|
package tools
|
||||||
|
|
||||||
// getInput is a stub implementation for when no platform-specific build tags are set.
|
import (
|
||||||
// This allows golangci-lint to typecheck the code without errors.
|
// Tool imports for go:generate.
|
||||||
// The actual implementations are provided in platform-specific files.
|
_ "github.com/fjl/gencodec"
|
||||||
func getInput() []byte {
|
_ "golang.org/x/tools/cmd/stringer"
|
||||||
panic("stub")
|
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
}
|
)
|
||||||
32
circle.yml
Normal file
32
circle.yml
Normal 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
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 = ð.StatusPacket{
|
status = ð.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(),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 := ð.GetReceiptsPacket{
|
req := ð.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
|
||||||
|
|
|
||||||
BIN
cmd/devp2p/internal/ethtest/testdata/chain.rlp
vendored
BIN
cmd/devp2p/internal/ethtest/testdata/chain.rlp
vendored
Binary file not shown.
|
|
@ -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"
|
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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"
|
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
]
|
]
|
||||||
|
|
|
||||||
6976
cmd/devp2p/internal/ethtest/testdata/headstate.json
vendored
6976
cmd/devp2p/internal/ethtest/testdata/headstate.json
vendored
File diff suppressed because it is too large
Load diff
21721
cmd/devp2p/internal/ethtest/testdata/newpayload.json
vendored
21721
cmd/devp2p/internal/ethtest/testdata/newpayload.json
vendored
File diff suppressed because it is too large
Load diff
5378
cmd/devp2p/internal/ethtest/testdata/txinfo.json
vendored
5378
cmd/devp2p/internal/ethtest/testdata/txinfo.json
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -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, ð.BlockHeadersPacket{
|
recvConn.Write(ethProto, eth.BlockHeadersMsg, ð.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, ð.BlockHeadersPacket{
|
recvConn.Write(ethProto, eth.BlockHeadersMsg, ð.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))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
135
cmd/era/main.go
135
cmd/era/main.go
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.PathScheme, 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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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!
|
||||||
|
|
|
||||||
|
|
@ -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()...)
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/1/exp.json
vendored
5
cmd/evm/testdata/1/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
10
cmd/evm/testdata/13/exp2.json
vendored
10
cmd/evm/testdata/13/exp2.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/23/exp.json
vendored
5
cmd/evm/testdata/23/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
10
cmd/evm/testdata/24/exp.json
vendored
10
cmd/evm/testdata/24/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/25/exp.json
vendored
5
cmd/evm/testdata/25/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
7
cmd/evm/testdata/28/exp.json
vendored
7
cmd/evm/testdata/28/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/29/exp.json
vendored
5
cmd/evm/testdata/29/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/3/exp.json
vendored
5
cmd/evm/testdata/3/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
10
cmd/evm/testdata/30/exp.json
vendored
10
cmd/evm/testdata/30/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
5
cmd/evm/testdata/33/exp.json
vendored
5
cmd/evm/testdata/33/exp.json
vendored
|
|
@ -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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
6
cmd/evm/testdata/34/README.md
vendored
6
cmd/evm/testdata/34/README.md
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
This test verifies that Osaka fork blob gas calculation works correctly when
|
|
||||||
parentBaseFee is provided. It tests the EIP-7918 reserve price calculation
|
|
||||||
which requires parent.BaseFee to be properly set.
|
|
||||||
|
|
||||||
Regression test for: nil pointer dereference when parent.BaseFee was not
|
|
||||||
included in the parent header during Osaka fork blob gas calculations.
|
|
||||||
6
cmd/evm/testdata/34/alloc.json
vendored
6
cmd/evm/testdata/34/alloc.json
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
|
||||||
"balance": "0x1000000000000000000",
|
|
||||||
"nonce": "0x0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
cmd/evm/testdata/34/env.json
vendored
18
cmd/evm/testdata/34/env.json
vendored
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"currentCoinbase": "0x0000000000000000000000000000000000000000",
|
|
||||||
"currentDifficulty": "0x0",
|
|
||||||
"currentRandom": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"currentGasLimit": "0x5f5e100",
|
|
||||||
"currentNumber": "0x1",
|
|
||||||
"currentTimestamp": "0x1000",
|
|
||||||
"parentTimestamp": "0x0",
|
|
||||||
"currentBaseFee": "0x10",
|
|
||||||
"parentBaseFee": "0x0a",
|
|
||||||
"parentGasUsed": "0x0",
|
|
||||||
"parentGasLimit": "0x5f5e100",
|
|
||||||
"currentExcessBlobGas": "0x0",
|
|
||||||
"parentExcessBlobGas": "0x0",
|
|
||||||
"parentBlobGasUsed": "0x20000",
|
|
||||||
"parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"withdrawals": []
|
|
||||||
}
|
|
||||||
23
cmd/evm/testdata/34/exp.json
vendored
23
cmd/evm/testdata/34/exp.json
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
{
|
|
||||||
"alloc": {
|
|
||||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
|
||||||
"balance": "0x1000000000000000000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"result": {
|
|
||||||
"stateRoot": "0x01c28492482a1a1f66224726ef1059a7036fce69d1d2c991b65cd013725d5742",
|
|
||||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
||||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
||||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
|
||||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"currentDifficulty": null,
|
|
||||||
"receipts": [],
|
|
||||||
"gasUsed": "0x0",
|
|
||||||
"currentBaseFee": "0x10",
|
|
||||||
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
|
||||||
"currentExcessBlobGas": "0x0",
|
|
||||||
"blobGasUsed": "0x0",
|
|
||||||
"requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
||||||
"requests": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
cmd/evm/testdata/34/txs.json
vendored
1
cmd/evm/testdata/34/txs.json
vendored
|
|
@ -1 +0,0 @@
|
||||||
[]
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
@ -44,8 +43,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/internal/debug"
|
"github.com/ethereum/go-ethereum/internal/debug"
|
||||||
"github.com/ethereum/go-ethereum/internal/era"
|
"github.com/ethereum/go-ethereum/internal/era"
|
||||||
"github.com/ethereum/go-ethereum/internal/era/eradl"
|
"github.com/ethereum/go-ethereum/internal/era/eradl"
|
||||||
"github.com/ethereum/go-ethereum/internal/era/execdb"
|
|
||||||
"github.com/ethereum/go-ethereum/internal/era/onedb"
|
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
|
|
@ -62,8 +59,6 @@ var (
|
||||||
Flags: slices.Concat([]cli.Flag{
|
Flags: slices.Concat([]cli.Flag{
|
||||||
utils.CachePreimagesFlag,
|
utils.CachePreimagesFlag,
|
||||||
utils.OverrideOsaka,
|
utils.OverrideOsaka,
|
||||||
utils.OverrideBPO1,
|
|
||||||
utils.OverrideBPO2,
|
|
||||||
utils.OverrideVerkle,
|
utils.OverrideVerkle,
|
||||||
}, utils.DatabaseFlags),
|
}, utils.DatabaseFlags),
|
||||||
Description: `
|
Description: `
|
||||||
|
|
@ -99,7 +94,6 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
|
||||||
utils.CacheNoPrefetchFlag,
|
utils.CacheNoPrefetchFlag,
|
||||||
utils.CachePreimagesFlag,
|
utils.CachePreimagesFlag,
|
||||||
utils.NoCompactionFlag,
|
utils.NoCompactionFlag,
|
||||||
utils.LogSlowBlockFlag,
|
|
||||||
utils.MetricsEnabledFlag,
|
utils.MetricsEnabledFlag,
|
||||||
utils.MetricsEnabledExpensiveFlag,
|
utils.MetricsEnabledExpensiveFlag,
|
||||||
utils.MetricsHTTPFlag,
|
utils.MetricsHTTPFlag,
|
||||||
|
|
@ -111,11 +105,9 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
|
||||||
utils.MetricsInfluxDBUsernameFlag,
|
utils.MetricsInfluxDBUsernameFlag,
|
||||||
utils.MetricsInfluxDBPasswordFlag,
|
utils.MetricsInfluxDBPasswordFlag,
|
||||||
utils.MetricsInfluxDBTagsFlag,
|
utils.MetricsInfluxDBTagsFlag,
|
||||||
utils.MetricsInfluxDBIntervalFlag,
|
|
||||||
utils.MetricsInfluxDBTokenFlag,
|
utils.MetricsInfluxDBTokenFlag,
|
||||||
utils.MetricsInfluxDBBucketFlag,
|
utils.MetricsInfluxDBBucketFlag,
|
||||||
utils.MetricsInfluxDBOrganizationFlag,
|
utils.MetricsInfluxDBOrganizationFlag,
|
||||||
utils.StateSizeTrackingFlag,
|
|
||||||
utils.TxLookupLimitFlag,
|
utils.TxLookupLimitFlag,
|
||||||
utils.VMTraceFlag,
|
utils.VMTraceFlag,
|
||||||
utils.VMTraceJsonConfigFlag,
|
utils.VMTraceJsonConfigFlag,
|
||||||
|
|
@ -124,8 +116,6 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
|
||||||
utils.LogNoHistoryFlag,
|
utils.LogNoHistoryFlag,
|
||||||
utils.LogExportCheckpointsFlag,
|
utils.LogExportCheckpointsFlag,
|
||||||
utils.StateHistoryFlag,
|
utils.StateHistoryFlag,
|
||||||
utils.TrienodeHistoryFlag,
|
|
||||||
utils.TrienodeHistoryFullValueCheckpointFlag,
|
|
||||||
}, utils.DatabaseFlags, debug.Flags),
|
}, utils.DatabaseFlags, debug.Flags),
|
||||||
Before: func(ctx *cli.Context) error {
|
Before: func(ctx *cli.Context) error {
|
||||||
flags.MigrateGlobalFlags(ctx)
|
flags.MigrateGlobalFlags(ctx)
|
||||||
|
|
@ -157,7 +147,7 @@ be gzipped.`,
|
||||||
Name: "import-history",
|
Name: "import-history",
|
||||||
Usage: "Import an Era archive",
|
Usage: "Import an Era archive",
|
||||||
ArgsUsage: "<dir>",
|
ArgsUsage: "<dir>",
|
||||||
Flags: slices.Concat([]cli.Flag{utils.TxLookupLimitFlag, utils.TransactionHistoryFlag, utils.EraFormatFlag}, utils.DatabaseFlags, utils.NetworkFlags),
|
Flags: slices.Concat([]cli.Flag{utils.TxLookupLimitFlag, utils.TransactionHistoryFlag}, utils.DatabaseFlags, utils.NetworkFlags),
|
||||||
Description: `
|
Description: `
|
||||||
The import-history command will import blocks and their corresponding receipts
|
The import-history command will import blocks and their corresponding receipts
|
||||||
from Era archives.
|
from Era archives.
|
||||||
|
|
@ -168,7 +158,7 @@ from Era archives.
|
||||||
Name: "export-history",
|
Name: "export-history",
|
||||||
Usage: "Export blockchain history to Era archives",
|
Usage: "Export blockchain history to Era archives",
|
||||||
ArgsUsage: "<dir> <first> <last>",
|
ArgsUsage: "<dir> <first> <last>",
|
||||||
Flags: slices.Concat([]cli.Flag{utils.EraFormatFlag}, utils.DatabaseFlags),
|
Flags: utils.DatabaseFlags,
|
||||||
Description: `
|
Description: `
|
||||||
The export-history command will export blocks and their corresponding receipts
|
The export-history command will export blocks and their corresponding receipts
|
||||||
into Era archives. Eras are typically packaged in steps of 8192 blocks.
|
into Era archives. Eras are typically packaged in steps of 8192 blocks.
|
||||||
|
|
@ -283,14 +273,6 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
v := ctx.Uint64(utils.OverrideOsaka.Name)
|
v := ctx.Uint64(utils.OverrideOsaka.Name)
|
||||||
overrides.OverrideOsaka = &v
|
overrides.OverrideOsaka = &v
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.OverrideBPO1.Name) {
|
|
||||||
v := ctx.Uint64(utils.OverrideBPO1.Name)
|
|
||||||
overrides.OverrideBPO1 = &v
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.OverrideBPO2.Name) {
|
|
||||||
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
|
||||||
overrides.OverrideBPO2 = &v
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
||||||
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
||||||
overrides.OverrideVerkle = &v
|
overrides.OverrideVerkle = &v
|
||||||
|
|
@ -299,10 +281,10 @@ func initGenesis(ctx *cli.Context) error {
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, false)
|
chaindb := utils.MakeChainDatabase(ctx, stack, false)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil)
|
_, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to write genesis block: %v", err)
|
utils.Fatalf("Failed to write genesis block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -520,27 +502,15 @@ func importHistory(ctx *cli.Context) error {
|
||||||
network = networks[0]
|
network = networks[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
if err := utils.ImportHistory(chain, dir, network); err != nil {
|
||||||
format = ctx.String(utils.EraFormatFlag.Name)
|
|
||||||
from func(era.ReadAtSeekCloser) (era.Era, error)
|
|
||||||
)
|
|
||||||
switch format {
|
|
||||||
case "era1", "era":
|
|
||||||
from = onedb.From
|
|
||||||
case "erae":
|
|
||||||
from = execdb.From
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown --era.format %q (expected 'era1' or 'erae')", format)
|
|
||||||
}
|
|
||||||
if err := utils.ImportHistory(chain, dir, network, from); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Import done in %v\n", time.Since(start))
|
fmt.Printf("Import done in %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// exportHistory exports chain history in Era archives at a specified directory.
|
// exportHistory exports chain history in Era archives at a specified
|
||||||
|
// directory.
|
||||||
func exportHistory(ctx *cli.Context) error {
|
func exportHistory(ctx *cli.Context) error {
|
||||||
if ctx.Args().Len() != 3 {
|
if ctx.Args().Len() != 3 {
|
||||||
utils.Fatalf("usage: %s", ctx.Command.ArgsUsage)
|
utils.Fatalf("usage: %s", ctx.Command.ArgsUsage)
|
||||||
|
|
@ -566,26 +536,10 @@ func exportHistory(ctx *cli.Context) error {
|
||||||
if head := chain.CurrentSnapBlock(); uint64(last) > head.Number.Uint64() {
|
if head := chain.CurrentSnapBlock(); uint64(last) > head.Number.Uint64() {
|
||||||
utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64())
|
utils.Fatalf("Export error: block number %d larger than head block %d\n", uint64(last), head.Number.Uint64())
|
||||||
}
|
}
|
||||||
|
err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), uint64(era.MaxEra1Size))
|
||||||
var (
|
if err != nil {
|
||||||
format = ctx.String(utils.EraFormatFlag.Name)
|
|
||||||
filename func(network string, epoch int, root common.Hash) string
|
|
||||||
newBuilder func(w io.Writer) era.Builder
|
|
||||||
)
|
|
||||||
switch format {
|
|
||||||
case "era1", "era":
|
|
||||||
newBuilder = func(w io.Writer) era.Builder { return onedb.NewBuilder(w) }
|
|
||||||
filename = func(network string, epoch int, root common.Hash) string { return onedb.Filename(network, epoch, root) }
|
|
||||||
case "erae":
|
|
||||||
newBuilder = func(w io.Writer) era.Builder { return execdb.NewBuilder(w) }
|
|
||||||
filename = func(network string, epoch int, root common.Hash) string { return execdb.Filename(network, epoch, root) }
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown archive format %q (use 'era1' or 'erae')", format)
|
|
||||||
}
|
|
||||||
if err := utils.ExportHistory(chain, dir, uint64(first), uint64(last), newBuilder, filename); err != nil {
|
|
||||||
utils.Fatalf("Export error: %v\n", err)
|
utils.Fatalf("Export error: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Export done in %v\n", time.Since(start))
|
fmt.Printf("Export done in %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -681,7 +635,7 @@ func dump(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup
|
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
state, err := state.New(root, state.NewDatabase(triedb, nil))
|
state, err := state.New(root, state.NewDatabase(triedb, nil))
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/beacon/blsync"
|
"github.com/ethereum/go-ethereum/beacon/blsync"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/eth/catalyst"
|
"github.com/ethereum/go-ethereum/eth/catalyst"
|
||||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||||
"github.com/ethereum/go-ethereum/internal/flags"
|
"github.com/ethereum/go-ethereum/internal/flags"
|
||||||
"github.com/ethereum/go-ethereum/internal/telemetry/tracesetup"
|
|
||||||
"github.com/ethereum/go-ethereum/internal/version"
|
"github.com/ethereum/go-ethereum/internal/version"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
@ -227,28 +227,14 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
v := ctx.Uint64(utils.OverrideOsaka.Name)
|
v := ctx.Uint64(utils.OverrideOsaka.Name)
|
||||||
cfg.Eth.OverrideOsaka = &v
|
cfg.Eth.OverrideOsaka = &v
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.OverrideBPO1.Name) {
|
|
||||||
v := ctx.Uint64(utils.OverrideBPO1.Name)
|
|
||||||
cfg.Eth.OverrideBPO1 = &v
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.OverrideBPO2.Name) {
|
|
||||||
v := ctx.Uint64(utils.OverrideBPO2.Name)
|
|
||||||
cfg.Eth.OverrideBPO2 = &v
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
if ctx.IsSet(utils.OverrideVerkle.Name) {
|
||||||
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
v := ctx.Uint64(utils.OverrideVerkle.Name)
|
||||||
cfg.Eth.OverrideVerkle = &v
|
cfg.Eth.OverrideVerkle = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start metrics export if enabled.
|
// Start metrics export if enabled
|
||||||
utils.SetupMetrics(&cfg.Metrics)
|
utils.SetupMetrics(&cfg.Metrics)
|
||||||
|
|
||||||
// Setup OpenTelemetry reporting if enabled.
|
|
||||||
if err := tracesetup.SetupTelemetry(cfg.Node.OpenTelemetry, stack); err != nil {
|
|
||||||
utils.Fatalf("failed to setup OpenTelemetry: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add Ethereum service.
|
|
||||||
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
||||||
|
|
||||||
// Create gauge with geth system and build information
|
// Create gauge with geth system and build information
|
||||||
|
|
@ -279,11 +265,11 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
// Configure synchronization override service
|
// Configure synchronization override service
|
||||||
var synctarget common.Hash
|
var synctarget common.Hash
|
||||||
if ctx.IsSet(utils.SyncTargetFlag.Name) {
|
if ctx.IsSet(utils.SyncTargetFlag.Name) {
|
||||||
target := ctx.String(utils.SyncTargetFlag.Name)
|
hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name))
|
||||||
if !common.IsHexHash(target) {
|
if len(hex) != common.HashLength {
|
||||||
utils.Fatalf("sync target hash is not a valid hex hash: %s", target)
|
utils.Fatalf("invalid sync target length: have %d, want %d", len(hex), common.HashLength)
|
||||||
}
|
}
|
||||||
synctarget = common.HexToHash(target)
|
synctarget = common.BytesToHash(hex)
|
||||||
}
|
}
|
||||||
utils.RegisterSyncOverrideService(stack, eth, synctarget, ctx.Bool(utils.ExitWhenSyncedFlag.Name))
|
utils.RegisterSyncOverrideService(stack, eth, synctarget, ctx.Bool(utils.ExitWhenSyncedFlag.Name))
|
||||||
|
|
||||||
|
|
@ -377,9 +363,6 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
||||||
cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name)
|
cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name)
|
||||||
}
|
}
|
||||||
if ctx.IsSet(utils.MetricsInfluxDBIntervalFlag.Name) {
|
|
||||||
cfg.Metrics.InfluxDBInterval = ctx.Duration(utils.MetricsInfluxDBIntervalFlag.Name)
|
|
||||||
}
|
|
||||||
if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
||||||
cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
||||||
}
|
}
|
||||||
|
|
@ -408,9 +391,9 @@ func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
||||||
ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name)
|
ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name)
|
||||||
|
|
||||||
if enableExport && v2FlagIsSet {
|
if enableExport && v2FlagIsSet {
|
||||||
utils.Fatalf("Flags --%s, --%s, --%s are only available for influxdb-v2", utils.MetricsInfluxDBOrganizationFlag.Name, utils.MetricsInfluxDBTokenFlag.Name, utils.MetricsInfluxDBBucketFlag.Name)
|
utils.Fatalf("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2")
|
||||||
} else if enableExportV2 && v1FlagIsSet {
|
} else if enableExportV2 && v1FlagIsSet {
|
||||||
utils.Fatalf("Flags --%s, --%s are only available for influxdb-v1", utils.MetricsInfluxDBUsernameFlag.Name, utils.MetricsInfluxDBPasswordFlag.Name)
|
utils.Fatalf("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ipcAPIs = "admin:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 testing:1.0 txpool:1.0 web3:1.0"
|
ipcAPIs = "admin:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0"
|
||||||
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
|
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -39,9 +39,8 @@ const (
|
||||||
// child g gets a temporary data directory.
|
// child g gets a temporary data directory.
|
||||||
func runMinimalGeth(t *testing.T, args ...string) *testgeth {
|
func runMinimalGeth(t *testing.T, args ...string) *testgeth {
|
||||||
// --holesky to make the 'writing genesis to disk' faster (no accounts)
|
// --holesky to make the 'writing genesis to disk' faster (no accounts)
|
||||||
// --networkid=1337 to avoid cache bump
|
|
||||||
// --syncmode=full to avoid allocating fast sync bloom
|
// --syncmode=full to avoid allocating fast sync bloom
|
||||||
allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0",
|
allArgs := []string{"--holesky", "--authrpc.port", "0", "--syncmode=full", "--port", "0",
|
||||||
"--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64",
|
"--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64",
|
||||||
"--datadir.minfreedisk", "0"}
|
"--datadir.minfreedisk", "0"}
|
||||||
return runGeth(t, append(allArgs, args...)...)
|
return runGeth(t, append(allArgs, args...)...)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -38,11 +37,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/internal/tablewriter"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"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/olekukonko/tablewriter"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -55,23 +54,6 @@ var (
|
||||||
Name: "remove.chain",
|
Name: "remove.chain",
|
||||||
Usage: "If set, selects the state data for removal",
|
Usage: "If set, selects the state data for removal",
|
||||||
}
|
}
|
||||||
inspectTrieTopFlag = &cli.IntFlag{
|
|
||||||
Name: "top",
|
|
||||||
Usage: "Print the top N results per ranking category",
|
|
||||||
Value: 10,
|
|
||||||
}
|
|
||||||
inspectTrieDumpPathFlag = &cli.StringFlag{
|
|
||||||
Name: "dump-path",
|
|
||||||
Usage: "Path for the trie statistics dump file",
|
|
||||||
}
|
|
||||||
inspectTrieSummarizeFlag = &cli.StringFlag{
|
|
||||||
Name: "summarize",
|
|
||||||
Usage: "Summarize an existing trie dump file (skip trie traversal)",
|
|
||||||
}
|
|
||||||
inspectTrieContractFlag = &cli.StringFlag{
|
|
||||||
Name: "contract",
|
|
||||||
Usage: "Inspect only the storage of the given contract address (skips full account trie walk)",
|
|
||||||
}
|
|
||||||
|
|
||||||
removedbCommand = &cli.Command{
|
removedbCommand = &cli.Command{
|
||||||
Action: removeDB,
|
Action: removeDB,
|
||||||
|
|
@ -93,7 +75,6 @@ Remove blockchain and state databases`,
|
||||||
dbCompactCmd,
|
dbCompactCmd,
|
||||||
dbGetCmd,
|
dbGetCmd,
|
||||||
dbDeleteCmd,
|
dbDeleteCmd,
|
||||||
dbInspectTrieCmd,
|
|
||||||
dbPutCmd,
|
dbPutCmd,
|
||||||
dbGetSlotsCmd,
|
dbGetSlotsCmd,
|
||||||
dbDumpFreezerIndex,
|
dbDumpFreezerIndex,
|
||||||
|
|
@ -112,22 +93,6 @@ Remove blockchain and state databases`,
|
||||||
Usage: "Inspect the storage size for each type of data in the database",
|
Usage: "Inspect the storage size for each type of data in the database",
|
||||||
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
|
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
|
||||||
}
|
}
|
||||||
dbInspectTrieCmd = &cli.Command{
|
|
||||||
Action: inspectTrie,
|
|
||||||
Name: "inspect-trie",
|
|
||||||
ArgsUsage: "<blocknum>",
|
|
||||||
Flags: slices.Concat([]cli.Flag{
|
|
||||||
utils.ExcludeStorageFlag,
|
|
||||||
inspectTrieTopFlag,
|
|
||||||
utils.OutputFileFlag,
|
|
||||||
inspectTrieDumpPathFlag,
|
|
||||||
inspectTrieSummarizeFlag,
|
|
||||||
inspectTrieContractFlag,
|
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags),
|
|
||||||
Usage: "Print detailed trie information about the structure of account trie and storage tries.",
|
|
||||||
Description: `This commands iterates the entrie trie-backed state. If the 'blocknum' is not specified,
|
|
||||||
the latest block number will be used by default.`,
|
|
||||||
}
|
|
||||||
dbCheckStateContentCmd = &cli.Command{
|
dbCheckStateContentCmd = &cli.Command{
|
||||||
Action: checkStateContent,
|
Action: checkStateContent,
|
||||||
Name: "check-state-content",
|
Name: "check-state-content",
|
||||||
|
|
@ -421,88 +386,6 @@ func checkStateContent(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspectTrie(ctx *cli.Context) error {
|
|
||||||
topN := ctx.Int(inspectTrieTopFlag.Name)
|
|
||||||
if topN <= 0 {
|
|
||||||
return fmt.Errorf("invalid --%s value %d (must be > 0)", inspectTrieTopFlag.Name, topN)
|
|
||||||
}
|
|
||||||
config := &trie.InspectConfig{
|
|
||||||
NoStorage: ctx.Bool(utils.ExcludeStorageFlag.Name),
|
|
||||||
TopN: topN,
|
|
||||||
Path: ctx.String(utils.OutputFileFlag.Name),
|
|
||||||
}
|
|
||||||
|
|
||||||
if summarizePath := ctx.String(inspectTrieSummarizeFlag.Name); summarizePath != "" {
|
|
||||||
if ctx.NArg() > 0 {
|
|
||||||
return fmt.Errorf("block number argument is not supported with --%s", inspectTrieSummarizeFlag.Name)
|
|
||||||
}
|
|
||||||
config.DumpPath = summarizePath
|
|
||||||
log.Info("Summarizing trie dump", "path", summarizePath, "top", topN)
|
|
||||||
return trie.Summarize(summarizePath, config)
|
|
||||||
}
|
|
||||||
if ctx.NArg() > 1 {
|
|
||||||
return fmt.Errorf("excessive number of arguments: %v", ctx.Command.ArgsUsage)
|
|
||||||
}
|
|
||||||
|
|
||||||
stack, _ := makeConfigNode(ctx)
|
|
||||||
db := utils.MakeChainDatabase(ctx, stack, false)
|
|
||||||
defer stack.Close()
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
var (
|
|
||||||
trieRoot common.Hash
|
|
||||||
hash common.Hash
|
|
||||||
number uint64
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case ctx.NArg() == 0 || ctx.Args().Get(0) == "latest":
|
|
||||||
head := rawdb.ReadHeadHeaderHash(db)
|
|
||||||
n, ok := rawdb.ReadHeaderNumber(db, head)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("could not load head block hash")
|
|
||||||
}
|
|
||||||
number = n
|
|
||||||
case ctx.Args().Get(0) == "snapshot":
|
|
||||||
trieRoot = rawdb.ReadSnapshotRoot(db)
|
|
||||||
number = math.MaxUint64
|
|
||||||
default:
|
|
||||||
var err error
|
|
||||||
number, err = strconv.ParseUint(ctx.Args().Get(0), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to parse blocknum, Args[0]: %v, err: %v", ctx.Args().Get(0), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if number != math.MaxUint64 {
|
|
||||||
hash = rawdb.ReadCanonicalHash(db, number)
|
|
||||||
if hash == (common.Hash{}) {
|
|
||||||
return fmt.Errorf("canonical hash for block %d not found", number)
|
|
||||||
}
|
|
||||||
blockHeader := rawdb.ReadHeader(db, hash, number)
|
|
||||||
trieRoot = blockHeader.Root
|
|
||||||
}
|
|
||||||
if trieRoot == (common.Hash{}) {
|
|
||||||
log.Error("Empty root hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
config.DumpPath = ctx.String(inspectTrieDumpPathFlag.Name)
|
|
||||||
if config.DumpPath == "" {
|
|
||||||
config.DumpPath = stack.ResolvePath("trie-dump.bin")
|
|
||||||
}
|
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false)
|
|
||||||
defer triedb.Close()
|
|
||||||
|
|
||||||
if contractAddr := ctx.String(inspectTrieContractFlag.Name); contractAddr != "" {
|
|
||||||
address := common.HexToAddress(contractAddr)
|
|
||||||
log.Info("Inspecting contract", "address", address, "root", trieRoot, "block", number)
|
|
||||||
return trie.InspectContract(triedb, db, trieRoot, address)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Inspecting trie", "root", trieRoot, "block", number, "dump", config.DumpPath, "top", topN)
|
|
||||||
return trie.Inspect(triedb, trieRoot, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func showDBStats(db ethdb.KeyValueStater) {
|
func showDBStats(db ethdb.KeyValueStater) {
|
||||||
stats, err := db.Stat()
|
stats, err := db.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -641,7 +524,7 @@ func dbDumpTrie(ctx *cli.Context) error {
|
||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, db, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -976,7 +859,7 @@ func inspectHistory(ctx *cli.Context) error {
|
||||||
db := utils.MakeChainDatabase(ctx, stack, true)
|
db := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, db, false, false, false)
|
triedb := utils.MakeTrieDatabase(ctx, db, false, false, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) {
|
||||||
have = censor(have, tStart, tEnd)
|
have = censor(have, tStart, tEnd)
|
||||||
want = censor(want, tStart, tEnd)
|
want = censor(want, tStart, tEnd)
|
||||||
if have != want {
|
if have != want {
|
||||||
t.Log(nicediff([]byte(have), []byte(want)))
|
t.Logf(nicediff([]byte(have), []byte(want)))
|
||||||
t.Fatalf("format %v, line %d\nhave %v\nwant %v", format, i, have, want)
|
t.Fatalf("format %v, line %d\nhave %v\nwant %v", format, i, have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +142,7 @@ func TestJsonLogging(t *testing.T) {
|
||||||
}
|
}
|
||||||
if !bytes.Equal(have, want) {
|
if !bytes.Equal(have, want) {
|
||||||
// show an intelligent diff
|
// show an intelligent diff
|
||||||
t.Log(nicediff(have, want))
|
t.Logf(nicediff(have, want))
|
||||||
t.Errorf("file content wrong")
|
t.Errorf("file content wrong")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +211,7 @@ func TestFileOut(t *testing.T) {
|
||||||
}
|
}
|
||||||
if !bytes.Equal(have, want) {
|
if !bytes.Equal(have, want) {
|
||||||
// show an intelligent diff
|
// show an intelligent diff
|
||||||
t.Log(nicediff(have, want))
|
t.Logf(nicediff(have, want))
|
||||||
t.Errorf("file content wrong")
|
t.Errorf("file content wrong")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +231,7 @@ func TestRotatingFileOut(t *testing.T) {
|
||||||
}
|
}
|
||||||
if !bytes.Equal(have, want) {
|
if !bytes.Equal(have, want) {
|
||||||
// show an intelligent diff
|
// show an intelligent diff
|
||||||
t.Log(nicediff(have, want))
|
t.Logf(nicediff(have, want))
|
||||||
t.Errorf("file content wrong")
|
t.Errorf("file content wrong")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,10 +63,7 @@ var (
|
||||||
utils.USBFlag,
|
utils.USBFlag,
|
||||||
utils.SmartCardDaemonPathFlag,
|
utils.SmartCardDaemonPathFlag,
|
||||||
utils.OverrideOsaka,
|
utils.OverrideOsaka,
|
||||||
utils.OverrideBPO1,
|
|
||||||
utils.OverrideBPO2,
|
|
||||||
utils.OverrideVerkle,
|
utils.OverrideVerkle,
|
||||||
utils.OverrideGenesisFlag,
|
|
||||||
utils.EnablePersonal, // deprecated
|
utils.EnablePersonal, // deprecated
|
||||||
utils.TxPoolLocalsFlag,
|
utils.TxPoolLocalsFlag,
|
||||||
utils.TxPoolNoLocalsFlag,
|
utils.TxPoolNoLocalsFlag,
|
||||||
|
|
@ -94,8 +91,6 @@ var (
|
||||||
utils.LogNoHistoryFlag,
|
utils.LogNoHistoryFlag,
|
||||||
utils.LogExportCheckpointsFlag,
|
utils.LogExportCheckpointsFlag,
|
||||||
utils.StateHistoryFlag,
|
utils.StateHistoryFlag,
|
||||||
utils.TrienodeHistoryFlag,
|
|
||||||
utils.TrienodeHistoryFullValueCheckpointFlag,
|
|
||||||
utils.LightKDFFlag,
|
utils.LightKDFFlag,
|
||||||
utils.EthRequiredBlocksFlag,
|
utils.EthRequiredBlocksFlag,
|
||||||
utils.LegacyWhitelistFlag, // deprecated
|
utils.LegacyWhitelistFlag, // deprecated
|
||||||
|
|
@ -120,7 +115,6 @@ var (
|
||||||
utils.MinerGasPriceFlag,
|
utils.MinerGasPriceFlag,
|
||||||
utils.MinerEtherbaseFlag, // deprecated
|
utils.MinerEtherbaseFlag, // deprecated
|
||||||
utils.MinerExtraDataFlag,
|
utils.MinerExtraDataFlag,
|
||||||
utils.MinerMaxBlobsFlag,
|
|
||||||
utils.MinerRecommitIntervalFlag,
|
utils.MinerRecommitIntervalFlag,
|
||||||
utils.MinerPendingFeeRecipientFlag,
|
utils.MinerPendingFeeRecipientFlag,
|
||||||
utils.MinerNewPayloadTimeoutFlag, // deprecated
|
utils.MinerNewPayloadTimeoutFlag, // deprecated
|
||||||
|
|
@ -139,8 +133,6 @@ var (
|
||||||
utils.VMEnableDebugFlag,
|
utils.VMEnableDebugFlag,
|
||||||
utils.VMTraceFlag,
|
utils.VMTraceFlag,
|
||||||
utils.VMTraceJsonConfigFlag,
|
utils.VMTraceJsonConfigFlag,
|
||||||
utils.VMWitnessStatsFlag,
|
|
||||||
utils.VMStatelessSelfValidationFlag,
|
|
||||||
utils.NetworkIdFlag,
|
utils.NetworkIdFlag,
|
||||||
utils.EthStatsURLFlag,
|
utils.EthStatsURLFlag,
|
||||||
utils.GpoBlocksFlag,
|
utils.GpoBlocksFlag,
|
||||||
|
|
@ -159,7 +151,6 @@ var (
|
||||||
utils.BeaconGenesisTimeFlag,
|
utils.BeaconGenesisTimeFlag,
|
||||||
utils.BeaconCheckpointFlag,
|
utils.BeaconCheckpointFlag,
|
||||||
utils.BeaconCheckpointFileFlag,
|
utils.BeaconCheckpointFileFlag,
|
||||||
utils.LogSlowBlockFlag,
|
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags)
|
}, utils.NetworkFlags, utils.DatabaseFlags)
|
||||||
|
|
||||||
rpcFlags = []cli.Flag{
|
rpcFlags = []cli.Flag{
|
||||||
|
|
@ -189,20 +180,9 @@ var (
|
||||||
utils.RPCGlobalGasCapFlag,
|
utils.RPCGlobalGasCapFlag,
|
||||||
utils.RPCGlobalEVMTimeoutFlag,
|
utils.RPCGlobalEVMTimeoutFlag,
|
||||||
utils.RPCGlobalTxFeeCapFlag,
|
utils.RPCGlobalTxFeeCapFlag,
|
||||||
utils.RPCGlobalLogQueryLimit,
|
|
||||||
utils.AllowUnprotectedTxs,
|
utils.AllowUnprotectedTxs,
|
||||||
utils.BatchRequestLimit,
|
utils.BatchRequestLimit,
|
||||||
utils.BatchResponseMaxSize,
|
utils.BatchResponseMaxSize,
|
||||||
utils.RPCTxSyncDefaultTimeoutFlag,
|
|
||||||
utils.RPCTxSyncMaxTimeoutFlag,
|
|
||||||
utils.RPCGlobalRangeLimitFlag,
|
|
||||||
utils.RPCTelemetryFlag,
|
|
||||||
utils.RPCTelemetryEndpointFlag,
|
|
||||||
utils.RPCTelemetryUserFlag,
|
|
||||||
utils.RPCTelemetryPasswordFlag,
|
|
||||||
utils.RPCTelemetryInstanceIDFlag,
|
|
||||||
utils.RPCTelemetryTagsFlag,
|
|
||||||
utils.RPCTelemetrySampleRatioFlag,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metricsFlags = []cli.Flag{
|
metricsFlags = []cli.Flag{
|
||||||
|
|
@ -216,12 +196,10 @@ var (
|
||||||
utils.MetricsInfluxDBUsernameFlag,
|
utils.MetricsInfluxDBUsernameFlag,
|
||||||
utils.MetricsInfluxDBPasswordFlag,
|
utils.MetricsInfluxDBPasswordFlag,
|
||||||
utils.MetricsInfluxDBTagsFlag,
|
utils.MetricsInfluxDBTagsFlag,
|
||||||
utils.MetricsInfluxDBIntervalFlag,
|
|
||||||
utils.MetricsEnableInfluxDBV2Flag,
|
utils.MetricsEnableInfluxDBV2Flag,
|
||||||
utils.MetricsInfluxDBTokenFlag,
|
utils.MetricsInfluxDBTokenFlag,
|
||||||
utils.MetricsInfluxDBBucketFlag,
|
utils.MetricsInfluxDBBucketFlag,
|
||||||
utils.MetricsInfluxDBOrganizationFlag,
|
utils.MetricsInfluxDBOrganizationFlag,
|
||||||
utils.StateSizeTrackingFlag,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -252,6 +230,7 @@ func init() {
|
||||||
javascriptCommand,
|
javascriptCommand,
|
||||||
// See misccmd.go:
|
// See misccmd.go:
|
||||||
versionCommand,
|
versionCommand,
|
||||||
|
versionCheckCommand,
|
||||||
licenseCommand,
|
licenseCommand,
|
||||||
// See config.go
|
// See config.go
|
||||||
dumpConfigCommand,
|
dumpConfigCommand,
|
||||||
|
|
@ -261,6 +240,8 @@ func init() {
|
||||||
utils.ShowDeprecated,
|
utils.ShowDeprecated,
|
||||||
// See snapshot.go
|
// See snapshot.go
|
||||||
snapshotCommand,
|
snapshotCommand,
|
||||||
|
// See verkle.go
|
||||||
|
verkleCommand,
|
||||||
}
|
}
|
||||||
if logTestCommand != nil {
|
if logTestCommand != nil {
|
||||||
app.Commands = append(app.Commands, logTestCommand)
|
app.Commands = append(app.Commands, logTestCommand)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
VersionCheckUrlFlag = &cli.StringFlag{
|
||||||
|
Name: "check.url",
|
||||||
|
Usage: "URL to use when checking vulnerabilities",
|
||||||
|
Value: "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json",
|
||||||
|
}
|
||||||
|
VersionCheckVersionFlag = &cli.StringFlag{
|
||||||
|
Name: "check.version",
|
||||||
|
Usage: "Version to check",
|
||||||
|
Value: version.ClientName(clientIdentifier),
|
||||||
|
}
|
||||||
versionCommand = &cli.Command{
|
versionCommand = &cli.Command{
|
||||||
Action: printVersion,
|
Action: printVersion,
|
||||||
Name: "version",
|
Name: "version",
|
||||||
|
|
@ -34,6 +44,20 @@ var (
|
||||||
ArgsUsage: " ",
|
ArgsUsage: " ",
|
||||||
Description: `
|
Description: `
|
||||||
The output of this command is supposed to be machine-readable.
|
The output of this command is supposed to be machine-readable.
|
||||||
|
`,
|
||||||
|
}
|
||||||
|
versionCheckCommand = &cli.Command{
|
||||||
|
Action: versionCheck,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
VersionCheckUrlFlag,
|
||||||
|
VersionCheckVersionFlag,
|
||||||
|
},
|
||||||
|
Name: "version-check",
|
||||||
|
Usage: "Checks (online) for known Geth security vulnerabilities",
|
||||||
|
ArgsUsage: "<versionstring (optional)>",
|
||||||
|
Description: `
|
||||||
|
The version-check command fetches vulnerability-information from https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json,
|
||||||
|
and displays information about any security vulnerabilities that affect the currently executing version.
|
||||||
`,
|
`,
|
||||||
}
|
}
|
||||||
licenseCommand = &cli.Command{
|
licenseCommand = &cli.Command{
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ func verifyState(ctx *cli.Context) error {
|
||||||
log.Error("Failed to load head block")
|
log.Error("Failed to load head block")
|
||||||
return errors.New("no head block")
|
return errors.New("no head block")
|
||||||
}
|
}
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -282,7 +282,7 @@ func traverseState(ctx *cli.Context) error {
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
headBlock := rawdb.ReadHeadBlock(chaindb)
|
headBlock := rawdb.ReadHeadBlock(chaindb)
|
||||||
|
|
@ -391,7 +391,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
headBlock := rawdb.ReadHeadBlock(chaindb)
|
headBlock := rawdb.ReadHeadBlock(chaindb)
|
||||||
|
|
@ -558,14 +558,20 @@ func dumpState(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, db, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
stateIt, err := utils.NewStateIterator(triedb, db, root)
|
snapConfig := snapshot.Config{
|
||||||
|
CacheSize: 256,
|
||||||
|
Recovery: false,
|
||||||
|
NoBuild: true,
|
||||||
|
AsyncBuild: false,
|
||||||
|
}
|
||||||
|
snaptree, err := snapshot.New(snapConfig, db, triedb, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
accIt, err := stateIt.AccountIterator(root, common.BytesToHash(conf.Start))
|
accIt, err := snaptree.AccountIterator(root, common.BytesToHash(conf.Start))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -599,7 +605,7 @@ func dumpState(ctx *cli.Context) error {
|
||||||
if !conf.SkipStorage {
|
if !conf.SkipStorage {
|
||||||
da.Storage = make(map[common.Hash]string)
|
da.Storage = make(map[common.Hash]string)
|
||||||
|
|
||||||
stIt, err := stateIt.StorageIterator(root, accIt.Hash(), common.Hash{})
|
stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -634,16 +640,16 @@ func snapshotExportPreimages(ctx *cli.Context) error {
|
||||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||||
defer chaindb.Close()
|
defer chaindb.Close()
|
||||||
|
|
||||||
triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false)
|
triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
var root common.Hash
|
var root common.Hash
|
||||||
if ctx.NArg() > 1 {
|
if ctx.NArg() > 1 {
|
||||||
hash := ctx.Args().Get(1)
|
rootBytes := common.FromHex(ctx.Args().Get(1))
|
||||||
if !common.IsHexHash(hash) {
|
if len(rootBytes) != common.HashLength {
|
||||||
return fmt.Errorf("invalid hash: %s", ctx.Args().Get(1))
|
return fmt.Errorf("invalid hash: %s", ctx.Args().Get(1))
|
||||||
}
|
}
|
||||||
root = common.HexToHash(hash)
|
root = common.BytesToHash(rootBytes)
|
||||||
} else {
|
} else {
|
||||||
headBlock := rawdb.ReadHeadBlock(chaindb)
|
headBlock := rawdb.ReadHeadBlock(chaindb)
|
||||||
if headBlock == nil {
|
if headBlock == nil {
|
||||||
|
|
@ -652,11 +658,17 @@ func snapshotExportPreimages(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
root = headBlock.Root()
|
root = headBlock.Root()
|
||||||
}
|
}
|
||||||
stateIt, err := utils.NewStateIterator(triedb, chaindb, root)
|
snapConfig := snapshot.Config{
|
||||||
|
CacheSize: 256,
|
||||||
|
Recovery: false,
|
||||||
|
NoBuild: true,
|
||||||
|
AsyncBuild: false,
|
||||||
|
}
|
||||||
|
snaptree, err := snapshot.New(snapConfig, chaindb, triedb, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return utils.ExportSnapshotPreimages(chaindb, stateIt, ctx.Args().First(), root)
|
return utils.ExportSnapshotPreimages(chaindb, snaptree, ctx.Args().First(), root)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkAccount iterates the snap data layers, and looks up the given account
|
// checkAccount iterates the snap data layers, and looks up the given account
|
||||||
|
|
|
||||||
202
cmd/geth/testdata/vcheck/data.json
vendored
Normal file
202
cmd/geth/testdata/vcheck/data.json
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "CorruptedDAG",
|
||||||
|
"uid": "GETH-2020-01",
|
||||||
|
"summary": "Mining nodes will generate erroneous PoW on epochs > `385`.",
|
||||||
|
"description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/pull/21793",
|
||||||
|
"https://blog.ethereum.org/2020/11/12/geth-security-release",
|
||||||
|
"https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49",
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-v592-xf75-856p"
|
||||||
|
],
|
||||||
|
"introduced": "v1.6.0",
|
||||||
|
"fixed": "v1.9.24",
|
||||||
|
"published": "2020-11-12",
|
||||||
|
"severity": "Medium",
|
||||||
|
"CVE": "CVE-2020-26240",
|
||||||
|
"check": "Geth\\/v1\\.(6|7|8)\\..*|Geth\\/v1\\.9\\.\\d-.*|Geth\\/v1\\.9\\.1.*|Geth\\/v1\\.9\\.2(0|1|2|3)-.*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Denial of service due to Go CVE-2020-28362",
|
||||||
|
"uid": "GETH-2020-02",
|
||||||
|
"summary": "A denial-of-service issue can be used to crash Geth nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`",
|
||||||
|
"description": "The DoS issue can be used to crash all Geth nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Geth (such as TurboGeth or ETC’s core-geth) which is built with versions of Go which contains the vulnerability.",
|
||||||
|
"links": [
|
||||||
|
"https://blog.ethereum.org/2020/11/12/geth-security-release",
|
||||||
|
"https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM",
|
||||||
|
"https://github.com/golang/go/issues/42552",
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-m6gx-rhvj-fh52"
|
||||||
|
],
|
||||||
|
"introduced": "v0.0.0",
|
||||||
|
"fixed": "v1.9.24",
|
||||||
|
"published": "2020-11-12",
|
||||||
|
"severity": "Critical",
|
||||||
|
"CVE": "CVE-2020-28362",
|
||||||
|
"check": "Geth.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ShallowCopy",
|
||||||
|
"uid": "GETH-2020-03",
|
||||||
|
"summary": "A consensus flaw in Geth, related to `datacopy` precompile",
|
||||||
|
"description": "Geth erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.",
|
||||||
|
"links": [
|
||||||
|
"https://blog.ethereum.org/2020/11/12/geth-security-release",
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-69v6-xc2j-r2jf"
|
||||||
|
],
|
||||||
|
"introduced": "v1.9.7",
|
||||||
|
"fixed": "v1.9.17",
|
||||||
|
"published": "2020-11-12",
|
||||||
|
"severity": "Critical",
|
||||||
|
"CVE": "CVE-2020-26241",
|
||||||
|
"check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Geth DoS via MULMOD",
|
||||||
|
"uid": "GETH-2020-04",
|
||||||
|
"summary": "A denial-of-service issue can be used to crash Geth nodes during block processing",
|
||||||
|
"description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the geth-dependency.\n",
|
||||||
|
"links": [
|
||||||
|
"https://blog.ethereum.org/2020/11/12/geth-security-release",
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m",
|
||||||
|
"https://github.com/holiman/uint256/releases/tag/v1.1.1",
|
||||||
|
"https://github.com/holiman/uint256/pull/80",
|
||||||
|
"https://github.com/ethereum/go-ethereum/pull/21368"
|
||||||
|
],
|
||||||
|
"introduced": "v1.9.16",
|
||||||
|
"fixed": "v1.9.18",
|
||||||
|
"published": "2020-11-12",
|
||||||
|
"severity": "Critical",
|
||||||
|
"CVE": "CVE-2020-26242",
|
||||||
|
"check": "Geth\\/v1\\.9.(16|17).*$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "LES Server DoS via GetProofsV2",
|
||||||
|
"uid": "GETH-2020-05",
|
||||||
|
"summary": "A DoS vulnerability can make a LES server crash.",
|
||||||
|
"description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running geth as a light server",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q",
|
||||||
|
"https://github.com/ethereum/go-ethereum/pull/21896"
|
||||||
|
],
|
||||||
|
"introduced": "v1.8.0",
|
||||||
|
"fixed": "v1.9.25",
|
||||||
|
"published": "2020-12-10",
|
||||||
|
"severity": "Medium",
|
||||||
|
"CVE": "CVE-2020-26264",
|
||||||
|
"check": "(Geth\\/v1\\.8\\.*)|(Geth\\/v1\\.9\\.\\d-.*)|(Geth\\/v1\\.9\\.1\\d-.*)|(Geth\\/v1\\.9\\.(20|21|22|23|24)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SELFDESTRUCT-recreate consensus flaw",
|
||||||
|
"uid": "GETH-2020-06",
|
||||||
|
"introduced": "v1.9.4",
|
||||||
|
"fixed": "v1.9.20",
|
||||||
|
"summary": "A consensus-vulnerability in Geth could cause a chain split, where vulnerable versions refuse to accept the canonical chain.",
|
||||||
|
"description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn geth, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in geth, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4"
|
||||||
|
],
|
||||||
|
"published": "2020-12-10",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2020-26265",
|
||||||
|
"check": "(Geth\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Geth\\/v1\\.9\\.1\\d-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Not ready for London upgrade",
|
||||||
|
"uid": "GETH-2021-01",
|
||||||
|
"summary": "The client is not ready for the 'London' technical upgrade, and will deviate from the canonical chain when the London upgrade occurs (at block '12965000' around August 4, 2021.",
|
||||||
|
"description": "At (or around) August 4, Ethereum will undergo a technical upgrade called 'London'. Clients not upgraded will fail to progress on the canonical chain.",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md",
|
||||||
|
"https://notes.ethereum.org/@timbeiko/ropsten-postmortem"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.1",
|
||||||
|
"fixed": "v1.10.6",
|
||||||
|
"published": "2021-07-22",
|
||||||
|
"severity": "High",
|
||||||
|
"check": "(Geth\\/v1\\.10\\.(1|2|3|4|5)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RETURNDATA corruption via datacopy",
|
||||||
|
"uid": "GETH-2021-02",
|
||||||
|
"summary": "A consensus-flaw in the Geth EVM could cause a node to deviate from the canonical chain.",
|
||||||
|
"description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll Geth versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/blob/master/docs/postmortems/2021-08-22-split-postmortem.md",
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-9856-9gg9-qcmq",
|
||||||
|
"https://github.com/ethereum/go-ethereum/releases/tag/v1.10.8"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.10.8",
|
||||||
|
"published": "2021-08-24",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2021-39137",
|
||||||
|
"check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious `snap/1` request",
|
||||||
|
"uid": "GETH-2021-03",
|
||||||
|
"summary": "A vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer, via the snap/1 protocol. The crash can be triggered by sending a malicious snap/1 GetTrieNodes package.",
|
||||||
|
"description": "The `snap/1` protocol handler contains two vulnerabilities related to the `GetTrieNodes` packet, which can be exploited to crash the node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v)",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities",
|
||||||
|
"https://github.com/ethereum/go-ethereum/pull/23657"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.10.9",
|
||||||
|
"published": "2021-10-24",
|
||||||
|
"severity": "Medium",
|
||||||
|
"CVE": "CVE-2021-41173",
|
||||||
|
"check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious p2p message",
|
||||||
|
"uid": "GETH-2022-01",
|
||||||
|
"summary": "A vulnerable node can crash via p2p messages sent from an attacker node, if running with non-default log options.",
|
||||||
|
"description": "A vulnerable node, if configured to use high verbosity logging, can be made to crash when handling specially crafted p2p messages sent from an attacker node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5)",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities",
|
||||||
|
"https://github.com/ethereum/go-ethereum/pull/24507"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.10.17",
|
||||||
|
"published": "2022-05-11",
|
||||||
|
"severity": "Low",
|
||||||
|
"CVE": "CVE-2022-29177",
|
||||||
|
"check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious p2p message",
|
||||||
|
"uid": "GETH-2023-01",
|
||||||
|
"summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.",
|
||||||
|
"description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.12.1",
|
||||||
|
"published": "2023-09-06",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2023-40591",
|
||||||
|
"check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoS via malicious p2p message",
|
||||||
|
"uid": "GETH-2024-01",
|
||||||
|
"summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.",
|
||||||
|
"description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)",
|
||||||
|
"links": [
|
||||||
|
"https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652",
|
||||||
|
"https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities"
|
||||||
|
],
|
||||||
|
"introduced": "v1.10.0",
|
||||||
|
"fixed": "v1.13.15",
|
||||||
|
"published": "2024-05-06",
|
||||||
|
"severity": "High",
|
||||||
|
"CVE": "CVE-2024-32972",
|
||||||
|
"check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$"
|
||||||
|
}
|
||||||
|
]
|
||||||
4
cmd/geth/testdata/vcheck/minisig-sigs-new/data.json.minisig
vendored
Normal file
4
cmd/geth/testdata/vcheck/minisig-sigs-new/data.json.minisig
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
untrusted comment: signature from minisign secret key
|
||||||
|
RUQkliYstQBOKHklFEYCUjepz81dyUuDmIAxjAvXa+icjGuKcjtVfV06G7qfOMSpplS5EcntU12n+AnGNyuOM8zIctaIWcfG2w0=
|
||||||
|
trusted comment: timestamp:1752094689 file:data.json hashed
|
||||||
|
u2e4wo4HBTU6viQTSY/NVBHoWoPFJnnTvLZS0FYl3JdvSOYi6+qpbEsDhAIFqq/n8VmlS/fPqqf7vKCNiAgjAA==
|
||||||
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1
vendored
Normal file
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
untrusted comment: signature from minisign secret key
|
||||||
|
RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0=
|
||||||
|
trusted comment: timestamp:1752094703 file:data.json
|
||||||
|
cNyq3ZGlqo785HtWODb9ejWqF0HhSeXuLGXzC7z1IhnDrBObWBJngYd3qBG1dQcYlHQ+bgB/On5mSyMFn4UoCQ==
|
||||||
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2
vendored
Normal file
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
untrusted comment: Here's a comment
|
||||||
|
RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0=
|
||||||
|
trusted comment: Here's a trusted comment
|
||||||
|
dL7lO8sqFFCOXJO/u8SgoDk2nlXGWPRDbOTJkChMbmtUp9PB7sG831basXkZ/0CQ/l/vG7AbPyMNEVZyJn5NCg==
|
||||||
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3
vendored
Normal file
4
cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
untrusted comment: One more (untrusted™) comment
|
||||||
|
RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0=
|
||||||
|
trusted comment: Here's a trusted comment
|
||||||
|
dL7lO8sqFFCOXJO/u8SgoDk2nlXGWPRDbOTJkChMbmtUp9PB7sG831basXkZ/0CQ/l/vG7AbPyMNEVZyJn5NCg==
|
||||||
2
cmd/geth/testdata/vcheck/minisign.pub
vendored
Normal file
2
cmd/geth/testdata/vcheck/minisign.pub
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: minisign public key 284E00B52C269624
|
||||||
|
RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp
|
||||||
2
cmd/geth/testdata/vcheck/minisign.sec
vendored
Normal file
2
cmd/geth/testdata/vcheck/minisign.sec
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
untrusted comment: minisign encrypted secret key
|
||||||
|
RWRTY0Iyz8kmPMKrqk6DCtlO9a33akKiaOQG1aLolqDxs52qvPoAAAACAAAAAAAAAEAAAAAArEiggdvyn6+WzTprirLtgiYQoU+ihz/HyGgjhuF+Pz2ddMduyCO+xjCHeq+vgVVW039fbsI8hW6LRGJZLBKV5/jdxCXAVVQE7qTQ6xpEdO0z8Z731/pV1hlspQXG2PNd16NMtwd9dWw=
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue