mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
Merge branch 'develop' of https://github.com/maticnetwork/bor into block-stm
This commit is contained in:
commit
6f16d006fd
65 changed files with 3827 additions and 727 deletions
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
|
|
@ -142,11 +142,11 @@ jobs:
|
|||
bash docker-heimdall-start-all.sh
|
||||
bash docker-bor-setup.sh
|
||||
bash docker-bor-start-all.sh
|
||||
sleep 120 && bash ganache-deployment-bor.sh
|
||||
sleep 120 && bash ganache-deployment-sync.sh
|
||||
sleep 120
|
||||
docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'admin.peers'"
|
||||
docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'eth.blockNumber'"
|
||||
cd -
|
||||
timeout 2m bash bor/integration-tests/bor_health.sh
|
||||
cd -
|
||||
bash ganache-deployment-bor.sh
|
||||
bash ganache-deployment-sync.sh
|
||||
|
||||
- name: Run smoke tests
|
||||
run: |
|
||||
|
|
|
|||
64
.github/workflows/security-ci.yml
vendored
Normal file
64
.github/workflows/security-ci.yml
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
name: Security CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
snyk:
|
||||
name: Snyk and Publish
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@master
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/golang@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --org=${{ secrets.SNYK_ORG }} --severity-threshold=medium --sarif-file-output=snyk.sarif
|
||||
- name: Upload result to GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
|
||||
snyk-code:
|
||||
name: Snyk Code and Publish
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@master
|
||||
- name: Run Snyk SAST to check for code vulnerabilities
|
||||
uses: snyk/actions/golang@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --org=${{ secrets.SNYK_ORG }} --sarif-file-output=snyk.sarif
|
||||
command: code test
|
||||
- name: Upload result to GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
|
||||
govuln:
|
||||
name: Run govuln check and Publish
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Running govulncheck
|
||||
uses: Templum/govulncheck-action@v0.0.8
|
||||
continue-on-error: true
|
||||
env:
|
||||
DEBUG: "true"
|
||||
with:
|
||||
go-version: 1.19
|
||||
vulncheck-version: latest
|
||||
package: ./...
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fail-on-vuln: true
|
||||
|
||||
- name: Upload govulncheck report
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: raw-report
|
||||
path: raw-report.json
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -54,4 +54,6 @@ profile.cov
|
|||
|
||||
dist
|
||||
|
||||
.dccache
|
||||
|
||||
*.csv
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ linters:
|
|||
- gocognit
|
||||
- gofmt
|
||||
# - gomnd
|
||||
- gomoddirectives
|
||||
# - gomoddirectives
|
||||
- gosec
|
||||
- makezero
|
||||
- nestif
|
||||
|
|
@ -65,10 +65,10 @@ linters-settings:
|
|||
|
||||
goimports:
|
||||
local-prefixes: github.com/ethereum/go-ethereum
|
||||
|
||||
|
||||
nestif:
|
||||
min-complexity: 5
|
||||
|
||||
|
||||
prealloc:
|
||||
for-loops: true
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ linters-settings:
|
|||
# By default list of stable checks is used.
|
||||
enabled-checks:
|
||||
- badLock
|
||||
- filepathJoin
|
||||
- filepathJoin
|
||||
- sortSlice
|
||||
- sprintfQuotedString
|
||||
- syncMapLoadAndDelete
|
||||
|
|
@ -185,4 +185,4 @@ issues:
|
|||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
#new: true
|
||||
new-from-rev: origin/master
|
||||
new-from-rev: origin/master
|
||||
|
|
|
|||
41
.snyk
Normal file
41
.snyk
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
|
||||
version: v1.25.0
|
||||
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
||||
ignore:
|
||||
'snyk:lic:golang:github.com:karalabe:usb:LGPL-3.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:06:37.028Z
|
||||
'snyk:lic:golang:github.com:mitchellh:cli:MPL-2.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:07:42.661Z
|
||||
'snyk:lic:golang:github.com:hashicorp:hcl:v2:MPL-2.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:08.112Z
|
||||
'snyk:lic:golang:github.com:hashicorp:go-multierror:MPL-2.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:14.673Z
|
||||
'snyk:lic:golang:github.com:hashicorp:go-bexpr:MPL-2.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:21.843Z
|
||||
'snyk:lic:golang:github.com:hashicorp:errwrap:MPL-2.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:28.257Z
|
||||
'snyk:lic:golang:github.com:ethereum:go-ethereum:LGPL-3.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:35.273Z
|
||||
'snyk:lic:golang:github.com:maticnetwork:polyproto:GPL-3.0':
|
||||
- '*':
|
||||
reason: 'As open source org, we have no issues with licenses'
|
||||
created: 2022-11-11T08:09:41.635Z
|
||||
'SNYK-GOLANG-GOLANGORGXNETHTTP2-3160322':
|
||||
- '*':
|
||||
reason: 'grpc working on a release to fix the issue'
|
||||
created: 2022-12-12T06:50:00.000Z
|
||||
patch: {}
|
||||
7
Makefile
7
Makefile
|
|
@ -59,7 +59,10 @@ ios:
|
|||
@echo "Import \"$(GOBIN)/Geth.framework\" to use the library."
|
||||
|
||||
test:
|
||||
$(GOTEST) --timeout 5m -shuffle=on -cover -coverprofile=cover.out $(TESTALL)
|
||||
$(GOTEST) --timeout 5m -shuffle=on -cover -short -coverprofile=cover.out -covermode=atomic $(TESTALL)
|
||||
|
||||
test-txpool-race:
|
||||
$(GOTEST) -run=TestPoolMiningDataRaces --timeout 600m -race -v ./core/
|
||||
|
||||
test-race:
|
||||
$(GOTEST) --timeout 15m -race -shuffle=on $(TESTALL)
|
||||
|
|
@ -75,7 +78,7 @@ lint:
|
|||
|
||||
lintci-deps:
|
||||
rm -f ./build/bin/golangci-lint
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.48.0
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.50.1
|
||||
|
||||
goimports:
|
||||
goimports -local "$(PACKAGE)" -w .
|
||||
|
|
|
|||
181
SECURITY.md
181
SECURITY.md
|
|
@ -1,175 +1,14 @@
|
|||
# Security Policy
|
||||
# Polygon Technology Security Information
|
||||
|
||||
## Supported Versions
|
||||
## Link to vulnerability disclosure details (Bug Bounty)
|
||||
- Websites and Applications: https://hackerone.com/polygon-technology
|
||||
- Smart Contracts: https://immunefi.com/bounty/polygon
|
||||
|
||||
Please see [Releases](https://github.com/ethereum/go-ethereum/releases). We recommend using the [most recently released version](https://github.com/ethereum/go-ethereum/releases/latest).
|
||||
## Languages that our team speaks and understands.
|
||||
Preferred-Languages: en
|
||||
|
||||
## Audit reports
|
||||
## Security-related job openings at Polygon.
|
||||
https://polygon.technology/careers
|
||||
|
||||
Audit reports are published in the `docs` folder: https://github.com/ethereum/go-ethereum/tree/master/docs/audits
|
||||
|
||||
| Scope | Date | Report Link |
|
||||
| ------- | ------- | ----------- |
|
||||
| `geth` | 20170425 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2017-04-25_Geth-audit_Truesec.pdf) |
|
||||
| `clef` | 20180914 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2018-09-14_Clef-audit_NCC.pdf) |
|
||||
| `Discv5` | 20191015 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2019-10-15_Discv5_audit_LeastAuthority.pdf) |
|
||||
| `Discv5` | 20200124 | [pdf](https://github.com/ethereum/go-ethereum/blob/master/docs/audits/2020-01-24_DiscV5_audit_Cure53.pdf) |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
**Please do not file a public ticket** mentioning the vulnerability.
|
||||
|
||||
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.
|
||||
|
||||
Fingerprint: `AE96 ED96 9E47 9B00 84F3 E17F E88D 3334 FA5F 6A0A`
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.1.6
|
||||
Comment: Hostname: pgp.mit.edu
|
||||
|
||||
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
|
||||
=arte
|
||||
-----END PGP PUBLIC KEY BLOCK------
|
||||
```
|
||||
## Polygon security contact details
|
||||
security@polygon.technology
|
||||
|
|
|
|||
38
build/ci.go
38
build/ci.go
|
|
@ -24,19 +24,18 @@ Usage: go run build/ci.go <command> <command flags/arguments>
|
|||
|
||||
Available commands are:
|
||||
|
||||
install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
|
||||
test [ -coverage ] [ packages... ] -- runs the tests
|
||||
lint -- runs certain pre-selected linters
|
||||
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts
|
||||
importkeys -- imports signing keys from env
|
||||
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
|
||||
nsis -- creates a Windows NSIS installer
|
||||
aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive
|
||||
xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework
|
||||
purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore
|
||||
install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
|
||||
test [ -coverage ] [ packages... ] -- runs the tests
|
||||
lint -- runs certain pre-selected linters
|
||||
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts
|
||||
importkeys -- imports signing keys from env
|
||||
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
|
||||
nsis -- creates a Windows NSIS installer
|
||||
aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive
|
||||
xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework
|
||||
purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore
|
||||
|
||||
For all commands, -n prevents execution of external programs (dry run mode).
|
||||
|
||||
*/
|
||||
package main
|
||||
|
||||
|
|
@ -59,6 +58,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/cespare/cp"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto/signify"
|
||||
"github.com/ethereum/go-ethereum/internal/build"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
|
@ -674,21 +674,27 @@ func doDebianSource(cmdline []string) {
|
|||
meta := newDebMetadata(distro, goboot, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables)
|
||||
pkgdir := stageDebianSource(*workdir, meta)
|
||||
|
||||
canonicalPath, err := common.VerifyPath(pkgdir)
|
||||
if err != nil {
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Add Go source code
|
||||
if err := build.ExtractArchive(gobundle, pkgdir); err != nil {
|
||||
if err := build.ExtractArchive(gobundle, canonicalPath); err != nil {
|
||||
log.Fatalf("Failed to extract Go sources: %v", err)
|
||||
}
|
||||
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".go")); err != nil {
|
||||
if err := os.Rename(filepath.Join(canonicalPath, "go"), filepath.Join(canonicalPath, ".go")); err != nil {
|
||||
log.Fatalf("Failed to rename Go source folder: %v", err)
|
||||
}
|
||||
// Add all dependency modules in compressed form
|
||||
os.MkdirAll(filepath.Join(pkgdir, ".mod", "cache"), 0755)
|
||||
if err := cp.CopyAll(filepath.Join(pkgdir, ".mod", "cache", "download"), filepath.Join(*workdir, "modgopath", "pkg", "mod", "cache", "download")); err != nil {
|
||||
os.MkdirAll(filepath.Join(canonicalPath, ".mod", "cache"), 0755)
|
||||
if err := cp.CopyAll(filepath.Join(canonicalPath, ".mod", "cache", "download"), filepath.Join(*workdir, "modgopath", "pkg", "mod", "cache", "download")); err != nil {
|
||||
log.Fatalf("Failed to copy Go module dependencies: %v", err)
|
||||
}
|
||||
// Run the packaging and upload to the PPA
|
||||
debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc", "-d", "-Zxz", "-nc")
|
||||
debuild.Dir = pkgdir
|
||||
debuild.Dir = canonicalPath
|
||||
build.MustRun(debuild)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -15,19 +15,24 @@
|
|||
"londonBlock": 22640000,
|
||||
"bor": {
|
||||
"jaipurBlock": 22770000,
|
||||
"delhiBlock": 29638656,
|
||||
"period": {
|
||||
"0": 2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"producerDelay": {
|
||||
"0": 6
|
||||
"0": 6,
|
||||
"29638656": 4
|
||||
},
|
||||
"sprint": {
|
||||
"0": 64
|
||||
"0": 64,
|
||||
"29638656": 16
|
||||
},
|
||||
"backupMultiplier": {
|
||||
"0": 2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"validatorContract": "0x0000000000000000000000000000000000001000",
|
||||
"stateReceiverContract": "0x0000000000000000000000000000000000001001",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
|
|
@ -32,7 +34,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/tests"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
type result struct {
|
||||
|
|
|
|||
|
|
@ -162,9 +162,16 @@ func main() {
|
|||
}
|
||||
}
|
||||
// Load up the account key and decrypt its password
|
||||
blob, err := ioutil.ReadFile(*accPassFlag)
|
||||
|
||||
canonicalPath, err := common.VerifyPath(*accPassFlag)
|
||||
if err != nil {
|
||||
log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err)
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
blob, err := ioutil.ReadFile(canonicalPath)
|
||||
if err != nil {
|
||||
log.Crit("Failed to read account password contents", "file", canonicalPath, "err", err)
|
||||
}
|
||||
pass := strings.TrimSuffix(string(blob), "\n")
|
||||
|
||||
|
|
|
|||
|
|
@ -1504,7 +1504,7 @@ func setPeerRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
|
|||
|
||||
if peerRequiredBlocks == "" {
|
||||
if ctx.GlobalIsSet(LegacyWhitelistFlag.Name) {
|
||||
log.Warn("The flag --rpc is deprecated and will be removed, please use --peer.requiredblocks")
|
||||
log.Warn("The flag --whitelist is deprecated and will be removed, please use --eth.requiredblocks")
|
||||
peerRequiredBlocks = ctx.GlobalString(LegacyWhitelistFlag.Name)
|
||||
} else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package debug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
|
|
@ -26,3 +27,26 @@ func Callers(show int) []string {
|
|||
|
||||
return callers
|
||||
}
|
||||
|
||||
func CodeLine() (string, string, int) {
|
||||
pc, filename, line, _ := runtime.Caller(1)
|
||||
return runtime.FuncForPC(pc).Name(), filename, line
|
||||
}
|
||||
|
||||
func CodeLineStr() string {
|
||||
pc, filename, line, _ := runtime.Caller(1)
|
||||
return fmt.Sprintf("%s:%d - %s", filename, line, runtime.FuncForPC(pc).Name())
|
||||
}
|
||||
|
||||
func Stack(all bool) []byte {
|
||||
buf := make([]byte, 4096)
|
||||
|
||||
for {
|
||||
n := runtime.Stack(buf, all)
|
||||
if n < len(buf) {
|
||||
return buf[:n]
|
||||
}
|
||||
|
||||
buf = make([]byte, 2*len(buf))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ package math
|
|||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// Various big integer limit values.
|
||||
|
|
@ -132,6 +134,7 @@ func MustParseBig256(s string) *big.Int {
|
|||
// BigPow returns a ** b as a big integer.
|
||||
func BigPow(a, b int64) *big.Int {
|
||||
r := big.NewInt(a)
|
||||
|
||||
return r.Exp(r, big.NewInt(b), nil)
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +143,15 @@ func BigMax(x, y *big.Int) *big.Int {
|
|||
if x.Cmp(y) < 0 {
|
||||
return y
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func BigMaxUint(x, y *uint256.Int) *uint256.Int {
|
||||
if x.Lt(y) {
|
||||
return y
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +160,15 @@ func BigMin(x, y *big.Int) *big.Int {
|
|||
if x.Cmp(y) > 0 {
|
||||
return y
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func BigMinUint256(x, y *uint256.Int) *uint256.Int {
|
||||
if x.Gt(y) {
|
||||
return y
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
|
|
@ -227,10 +248,10 @@ func U256Bytes(n *big.Int) []byte {
|
|||
// S256 interprets x as a two's complement number.
|
||||
// x must not exceed 256 bits (the result is undefined if it does) and is not modified.
|
||||
//
|
||||
// S256(0) = 0
|
||||
// S256(1) = 1
|
||||
// S256(2**255) = -2**255
|
||||
// S256(2**256-1) = -1
|
||||
// S256(0) = 0
|
||||
// S256(1) = 1
|
||||
// S256(2**255) = -2**255
|
||||
// S256(2**256-1) = -1
|
||||
func S256(x *big.Int) *big.Int {
|
||||
if x.Cmp(tt255) < 0 {
|
||||
return x
|
||||
|
|
|
|||
23
common/math/uint.go
Normal file
23
common/math/uint.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package math
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
var (
|
||||
U0 = uint256.NewInt(0)
|
||||
U1 = uint256.NewInt(1)
|
||||
U100 = uint256.NewInt(100)
|
||||
)
|
||||
|
||||
func U256LTE(a, b *uint256.Int) bool {
|
||||
return a.Lt(b) || a.Eq(b)
|
||||
}
|
||||
|
||||
func FromBig(v *big.Int) *uint256.Int {
|
||||
u, _ := uint256.FromBig(v)
|
||||
|
||||
return u
|
||||
}
|
||||
|
|
@ -47,3 +47,32 @@ func AbsolutePath(datadir string, filename string) string {
|
|||
}
|
||||
return filepath.Join(datadir, filename)
|
||||
}
|
||||
|
||||
// VerifyPath sanitizes the path to avoid Path Traversal vulnerability
|
||||
func VerifyPath(path string) (string, error) {
|
||||
c := filepath.Clean(path)
|
||||
|
||||
r, err := filepath.EvalSymlinks(c)
|
||||
if err != nil {
|
||||
return c, fmt.Errorf("unsafe or invalid path specified: %s", path)
|
||||
} else {
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyCrasher sanitizes the path to avoid Path Traversal vulnerability and reads the file from that path, returning its content
|
||||
func VerifyCrasher(crasher string) []byte {
|
||||
canonicalPath, err := VerifyPath(crasher)
|
||||
if err != nil {
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(canonicalPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", canonicalPath, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
|
|
|||
9
common/time.go
Normal file
9
common/time.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package common
|
||||
|
||||
import "time"
|
||||
|
||||
const TimeMilliseconds = "15:04:05.000"
|
||||
|
||||
func NowMilliseconds() string {
|
||||
return time.Now().Format(TimeMilliseconds)
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
|
@ -51,11 +52,16 @@ func Trace(ctx context.Context, spanName string) (context.Context, trace.Span) {
|
|||
return tr.Start(ctx, spanName)
|
||||
}
|
||||
|
||||
func Exec(ctx context.Context, spanName string, opts ...Option) {
|
||||
func Exec(ctx context.Context, instrumentationName, spanName string, opts ...Option) {
|
||||
var span trace.Span
|
||||
|
||||
tr := FromContext(ctx)
|
||||
|
||||
if tr == nil && len(instrumentationName) != 0 {
|
||||
tr = otel.GetTracerProvider().Tracer(instrumentationName)
|
||||
ctx = WithTracer(ctx, tr)
|
||||
}
|
||||
|
||||
if tr != nil {
|
||||
ctx, span = tr.Start(ctx, spanName)
|
||||
}
|
||||
|
|
@ -85,7 +91,7 @@ func ElapsedTime(ctx context.Context, span trace.Span, msg string, fn func(conte
|
|||
fn(ctx, span)
|
||||
|
||||
if span != nil {
|
||||
span.SetAttributes(attribute.Int(msg, int(time.Since(now).Milliseconds())))
|
||||
span.SetAttributes(attribute.Int(msg, int(time.Since(now).Microseconds())))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -821,7 +821,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead
|
|||
if IsSprintStart(headerNumber, c.config.CalculateSprint(headerNumber)) {
|
||||
cx := statefull.ChainContext{Chain: chain, Bor: c}
|
||||
|
||||
tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(finalizeCtx, "", "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
// check and commit span
|
||||
err = c.checkAndCommitSpan(finalizeCtx, state, header, cx)
|
||||
})
|
||||
|
|
@ -832,7 +832,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead
|
|||
}
|
||||
|
||||
if c.HeimdallClient != nil {
|
||||
tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(finalizeCtx, "", "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) {
|
||||
// commit states
|
||||
stateSyncData, err = c.CommitStates(finalizeCtx, state, header, cx)
|
||||
})
|
||||
|
|
@ -844,7 +844,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead
|
|||
}
|
||||
}
|
||||
|
||||
tracing.Exec(finalizeCtx, "bor.changeContractCodeIfNeeded", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(finalizeCtx, "", "bor.changeContractCodeIfNeeded", func(ctx context.Context, span trace.Span) {
|
||||
err = c.changeContractCodeIfNeeded(headerNumber, state)
|
||||
})
|
||||
|
||||
|
|
@ -854,7 +854,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead
|
|||
}
|
||||
|
||||
// No block rewards in PoA, so the state remains as it is
|
||||
tracing.Exec(finalizeCtx, "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(finalizeCtx, "", "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) {
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -92,3 +94,54 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// CalcBaseFee calculates the basefee of the header.
|
||||
func CalcBaseFeeUint(config *params.ChainConfig, parent *types.Header) *uint256.Int {
|
||||
var (
|
||||
initialBaseFeeUint = uint256.NewInt(params.InitialBaseFee)
|
||||
baseFeeChangeDenominatorUint64 = params.BaseFeeChangeDenominator(config.Bor, parent.Number)
|
||||
baseFeeChangeDenominatorUint = uint256.NewInt(baseFeeChangeDenominatorUint64)
|
||||
)
|
||||
|
||||
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
||||
if !config.IsLondon(parent.Number) {
|
||||
return initialBaseFeeUint.Clone()
|
||||
}
|
||||
|
||||
var (
|
||||
parentGasTarget = parent.GasLimit / params.ElasticityMultiplier
|
||||
parentGasTargetBig = uint256.NewInt(parentGasTarget)
|
||||
)
|
||||
|
||||
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
|
||||
if parent.GasUsed == parentGasTarget {
|
||||
return math.FromBig(parent.BaseFee)
|
||||
}
|
||||
|
||||
if parent.GasUsed > parentGasTarget {
|
||||
// If the parent block used more gas than its target, the baseFee should increase.
|
||||
gasUsedDelta := uint256.NewInt(parent.GasUsed - parentGasTarget)
|
||||
|
||||
parentBaseFee := math.FromBig(parent.BaseFee)
|
||||
x := gasUsedDelta.Mul(parentBaseFee, gasUsedDelta)
|
||||
y := x.Div(x, parentGasTargetBig)
|
||||
baseFeeDelta := math.BigMaxUint(
|
||||
x.Div(y, baseFeeChangeDenominatorUint),
|
||||
math.U1,
|
||||
)
|
||||
|
||||
return x.Add(parentBaseFee, baseFeeDelta)
|
||||
}
|
||||
|
||||
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
|
||||
gasUsedDelta := uint256.NewInt(parentGasTarget - parent.GasUsed)
|
||||
parentBaseFee := math.FromBig(parent.BaseFee)
|
||||
x := gasUsedDelta.Mul(parentBaseFee, gasUsedDelta)
|
||||
y := x.Div(x, parentGasTargetBig)
|
||||
baseFeeDelta := x.Div(y, baseFeeChangeDenominatorUint)
|
||||
|
||||
return math.BigMaxUint(
|
||||
x.Sub(parentBaseFee, baseFeeDelta),
|
||||
math.U0.Clone(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,13 @@ func (journal *txJournal) load(add func([]*types.Transaction) []error) error {
|
|||
if _, err := os.Stat(journal.path); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Open the journal for loading any past transactions
|
||||
input, err := os.Open(journal.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer input.Close()
|
||||
|
||||
// Temporarily discard any journal additions (don't double add on load)
|
||||
|
|
@ -80,29 +82,35 @@ func (journal *txJournal) load(add func([]*types.Transaction) []error) error {
|
|||
// appropriate progress counters. Then use this method to load all the
|
||||
// journaled transactions in small-ish batches.
|
||||
loadBatch := func(txs types.Transactions) {
|
||||
errs := add(txs)
|
||||
|
||||
dropped = len(errs)
|
||||
|
||||
for _, err := range add(txs) {
|
||||
if err != nil {
|
||||
log.Debug("Failed to add journaled transaction", "err", err)
|
||||
dropped++
|
||||
}
|
||||
log.Debug("Failed to add journaled transaction", "err", err)
|
||||
}
|
||||
}
|
||||
var (
|
||||
failure error
|
||||
batch types.Transactions
|
||||
)
|
||||
|
||||
for {
|
||||
// Parse the next transaction and terminate on error
|
||||
tx := new(types.Transaction)
|
||||
|
||||
if err = stream.Decode(tx); err != nil {
|
||||
if err != io.EOF {
|
||||
failure = err
|
||||
}
|
||||
|
||||
if batch.Len() > 0 {
|
||||
loadBatch(batch)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// New transaction parsed, queue up for later, import if threshold is reached
|
||||
total++
|
||||
|
||||
|
|
@ -111,6 +119,7 @@ func (journal *txJournal) load(add func([]*types.Transaction) []error) error {
|
|||
batch = batch[:0]
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Loaded local transaction journal", "transactions", total, "dropped", dropped)
|
||||
|
||||
return failure
|
||||
|
|
|
|||
236
core/tx_list.go
236
core/tx_list.go
|
|
@ -19,13 +19,15 @@ package core
|
|||
import (
|
||||
"container/heap"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
cmath "github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
|
|
@ -54,36 +56,67 @@ func (h *nonceHeap) Pop() interface{} {
|
|||
type txSortedMap struct {
|
||||
items map[uint64]*types.Transaction // Hash map storing the transaction data
|
||||
index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode)
|
||||
cache types.Transactions // Cache of the transactions already sorted
|
||||
m sync.RWMutex
|
||||
|
||||
cache types.Transactions // Cache of the transactions already sorted
|
||||
isEmpty bool
|
||||
cacheMu sync.RWMutex
|
||||
}
|
||||
|
||||
// newTxSortedMap creates a new nonce-sorted transaction map.
|
||||
func newTxSortedMap() *txSortedMap {
|
||||
return &txSortedMap{
|
||||
items: make(map[uint64]*types.Transaction),
|
||||
index: new(nonceHeap),
|
||||
items: make(map[uint64]*types.Transaction),
|
||||
index: new(nonceHeap),
|
||||
isEmpty: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves the current transactions associated with the given nonce.
|
||||
func (m *txSortedMap) Get(nonce uint64) *types.Transaction {
|
||||
m.m.RLock()
|
||||
defer m.m.RUnlock()
|
||||
|
||||
return m.items[nonce]
|
||||
}
|
||||
|
||||
func (m *txSortedMap) Has(nonce uint64) bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
m.m.RLock()
|
||||
defer m.m.RUnlock()
|
||||
|
||||
return m.items[nonce] != nil
|
||||
}
|
||||
|
||||
// Put inserts a new transaction into the map, also updating the map's nonce
|
||||
// index. If a transaction already exists with the same nonce, it's overwritten.
|
||||
func (m *txSortedMap) Put(tx *types.Transaction) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
nonce := tx.Nonce()
|
||||
if m.items[nonce] == nil {
|
||||
heap.Push(m.index, nonce)
|
||||
}
|
||||
m.items[nonce], m.cache = tx, nil
|
||||
|
||||
m.items[nonce] = tx
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.isEmpty = true
|
||||
m.cache = nil
|
||||
m.cacheMu.Unlock()
|
||||
}
|
||||
|
||||
// Forward removes all transactions from the map with a nonce lower than the
|
||||
// provided threshold. Every removed transaction is returned for any post-removal
|
||||
// maintenance.
|
||||
func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
var removed types.Transactions
|
||||
|
||||
// Pop off heap items until the threshold is reached
|
||||
|
|
@ -92,10 +125,15 @@ func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
|
|||
removed = append(removed, m.items[nonce])
|
||||
delete(m.items, nonce)
|
||||
}
|
||||
|
||||
// If we had a cached order, shift the front
|
||||
m.cacheMu.Lock()
|
||||
if m.cache != nil {
|
||||
hitCacheCounter.Inc(1)
|
||||
m.cache = m.cache[len(removed):]
|
||||
}
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
return removed
|
||||
}
|
||||
|
||||
|
|
@ -105,6 +143,9 @@ func (m *txSortedMap) Forward(threshold uint64) types.Transactions {
|
|||
// If you want to do several consecutive filterings, it's therefore better to first
|
||||
// do a .filter(func1) followed by .Filter(func2) or reheap()
|
||||
func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
removed := m.filter(filter)
|
||||
// If transactions were removed, the heap and cache are ruined
|
||||
if len(removed) > 0 {
|
||||
|
|
@ -115,11 +156,19 @@ func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transac
|
|||
|
||||
func (m *txSortedMap) reheap() {
|
||||
*m.index = make([]uint64, 0, len(m.items))
|
||||
|
||||
for nonce := range m.items {
|
||||
*m.index = append(*m.index, nonce)
|
||||
}
|
||||
|
||||
heap.Init(m.index)
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.cache = nil
|
||||
m.isEmpty = true
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
resetCacheGauge.Inc(1)
|
||||
}
|
||||
|
||||
// filter is identical to Filter, but **does not** regenerate the heap. This method
|
||||
|
|
@ -135,7 +184,12 @@ func (m *txSortedMap) filter(filter func(*types.Transaction) bool) types.Transac
|
|||
}
|
||||
}
|
||||
if len(removed) > 0 {
|
||||
m.cacheMu.Lock()
|
||||
m.cache = nil
|
||||
m.isEmpty = true
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
resetCacheGauge.Inc(1)
|
||||
}
|
||||
return removed
|
||||
}
|
||||
|
|
@ -143,45 +197,66 @@ func (m *txSortedMap) filter(filter func(*types.Transaction) bool) types.Transac
|
|||
// Cap places a hard limit on the number of items, returning all transactions
|
||||
// exceeding that limit.
|
||||
func (m *txSortedMap) Cap(threshold int) types.Transactions {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
// Short circuit if the number of items is under the limit
|
||||
if len(m.items) <= threshold {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise gather and drop the highest nonce'd transactions
|
||||
var drops types.Transactions
|
||||
|
||||
sort.Sort(*m.index)
|
||||
|
||||
for size := len(m.items); size > threshold; size-- {
|
||||
drops = append(drops, m.items[(*m.index)[size-1]])
|
||||
delete(m.items, (*m.index)[size-1])
|
||||
}
|
||||
|
||||
*m.index = (*m.index)[:threshold]
|
||||
heap.Init(m.index)
|
||||
|
||||
// If we had a cache, shift the back
|
||||
m.cacheMu.Lock()
|
||||
if m.cache != nil {
|
||||
m.cache = m.cache[:len(m.cache)-len(drops)]
|
||||
}
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
return drops
|
||||
}
|
||||
|
||||
// Remove deletes a transaction from the maintained map, returning whether the
|
||||
// transaction was found.
|
||||
func (m *txSortedMap) Remove(nonce uint64) bool {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
// Short circuit if no transaction is present
|
||||
_, ok := m.items[nonce]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Otherwise delete the transaction and fix the heap index
|
||||
for i := 0; i < m.index.Len(); i++ {
|
||||
if (*m.index)[i] == nonce {
|
||||
heap.Remove(m.index, i)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
delete(m.items, nonce)
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.cache = nil
|
||||
m.isEmpty = true
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
resetCacheGauge.Inc(1)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -194,55 +269,125 @@ func (m *txSortedMap) Remove(nonce uint64) bool {
|
|||
// prevent getting into and invalid state. This is not something that should ever
|
||||
// happen but better to be self correcting than failing!
|
||||
func (m *txSortedMap) Ready(start uint64) types.Transactions {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
// Short circuit if no transactions are available
|
||||
if m.index.Len() == 0 || (*m.index)[0] > start {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Otherwise start accumulating incremental transactions
|
||||
var ready types.Transactions
|
||||
|
||||
for next := (*m.index)[0]; m.index.Len() > 0 && (*m.index)[0] == next; next++ {
|
||||
ready = append(ready, m.items[next])
|
||||
delete(m.items, next)
|
||||
heap.Pop(m.index)
|
||||
}
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.cache = nil
|
||||
m.isEmpty = true
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
resetCacheGauge.Inc(1)
|
||||
|
||||
return ready
|
||||
}
|
||||
|
||||
// Len returns the length of the transaction map.
|
||||
func (m *txSortedMap) Len() int {
|
||||
m.m.RLock()
|
||||
defer m.m.RUnlock()
|
||||
|
||||
return len(m.items)
|
||||
}
|
||||
|
||||
func (m *txSortedMap) flatten() types.Transactions {
|
||||
// If the sorting was not cached yet, create and cache it
|
||||
if m.cache == nil {
|
||||
m.cache = make(types.Transactions, 0, len(m.items))
|
||||
m.cacheMu.Lock()
|
||||
defer m.cacheMu.Unlock()
|
||||
|
||||
if m.isEmpty {
|
||||
m.isEmpty = false // to simulate sync.Once
|
||||
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
m.m.RLock()
|
||||
|
||||
cache := make(types.Transactions, 0, len(m.items))
|
||||
|
||||
for _, tx := range m.items {
|
||||
m.cache = append(m.cache, tx)
|
||||
cache = append(cache, tx)
|
||||
}
|
||||
sort.Sort(types.TxByNonce(m.cache))
|
||||
|
||||
m.m.RUnlock()
|
||||
|
||||
// exclude sorting from locks
|
||||
sort.Sort(types.TxByNonce(cache))
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.cache = cache
|
||||
|
||||
reinitCacheGauge.Inc(1)
|
||||
missCacheCounter.Inc(1)
|
||||
} else {
|
||||
hitCacheCounter.Inc(1)
|
||||
}
|
||||
|
||||
return m.cache
|
||||
}
|
||||
|
||||
func (m *txSortedMap) lastElement() *types.Transaction {
|
||||
// If the sorting was not cached yet, create and cache it
|
||||
m.cacheMu.Lock()
|
||||
defer m.cacheMu.Unlock()
|
||||
|
||||
cache := m.cache
|
||||
|
||||
if m.isEmpty {
|
||||
m.isEmpty = false // to simulate sync.Once
|
||||
|
||||
m.cacheMu.Unlock()
|
||||
|
||||
cache = make(types.Transactions, 0, len(m.items))
|
||||
|
||||
m.m.RLock()
|
||||
|
||||
for _, tx := range m.items {
|
||||
cache = append(cache, tx)
|
||||
}
|
||||
|
||||
m.m.RUnlock()
|
||||
|
||||
// exclude sorting from locks
|
||||
sort.Sort(types.TxByNonce(cache))
|
||||
|
||||
m.cacheMu.Lock()
|
||||
m.cache = cache
|
||||
|
||||
reinitCacheGauge.Inc(1)
|
||||
missCacheCounter.Inc(1)
|
||||
} else {
|
||||
hitCacheCounter.Inc(1)
|
||||
}
|
||||
|
||||
return cache[len(cache)-1]
|
||||
}
|
||||
|
||||
// Flatten creates a nonce-sorted slice of transactions based on the loosely
|
||||
// sorted internal representation. The result of the sorting is cached in case
|
||||
// it's requested again before any modifications are made to the contents.
|
||||
func (m *txSortedMap) Flatten() types.Transactions {
|
||||
// Copy the cache to prevent accidental modifications
|
||||
cache := m.flatten()
|
||||
txs := make(types.Transactions, len(cache))
|
||||
copy(txs, cache)
|
||||
return txs
|
||||
return m.flatten()
|
||||
}
|
||||
|
||||
// LastElement returns the last element of a flattened list, thus, the
|
||||
// transaction with the highest nonce
|
||||
func (m *txSortedMap) LastElement() *types.Transaction {
|
||||
cache := m.flatten()
|
||||
return cache[len(cache)-1]
|
||||
return m.lastElement()
|
||||
}
|
||||
|
||||
// txList is a "list" of transactions belonging to an account, sorted by account
|
||||
|
|
@ -253,17 +398,16 @@ type txList struct {
|
|||
strict bool // Whether nonces are strictly continuous or not
|
||||
txs *txSortedMap // Heap indexed sorted hash map of the transactions
|
||||
|
||||
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
||||
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
||||
costcap *uint256.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
||||
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
||||
}
|
||||
|
||||
// newTxList create a new transaction list for maintaining nonce-indexable fast,
|
||||
// gapped, sortable transaction lists.
|
||||
func newTxList(strict bool) *txList {
|
||||
return &txList{
|
||||
strict: strict,
|
||||
txs: newTxSortedMap(),
|
||||
costcap: new(big.Int),
|
||||
strict: strict,
|
||||
txs: newTxSortedMap(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,31 +429,36 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran
|
|||
if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// thresholdFeeCap = oldFC * (100 + priceBump) / 100
|
||||
a := big.NewInt(100 + int64(priceBump))
|
||||
aFeeCap := new(big.Int).Mul(a, old.GasFeeCap())
|
||||
aTip := a.Mul(a, old.GasTipCap())
|
||||
a := uint256.NewInt(100 + priceBump)
|
||||
aFeeCap := uint256.NewInt(0).Mul(a, old.GasFeeCapUint())
|
||||
aTip := a.Mul(a, old.GasTipCapUint())
|
||||
|
||||
// thresholdTip = oldTip * (100 + priceBump) / 100
|
||||
b := big.NewInt(100)
|
||||
b := cmath.U100
|
||||
thresholdFeeCap := aFeeCap.Div(aFeeCap, b)
|
||||
thresholdTip := aTip.Div(aTip, b)
|
||||
|
||||
// We have to ensure that both the new fee cap and tip are higher than the
|
||||
// old ones as well as checking the percentage threshold to ensure that
|
||||
// this is accurate for low (Wei-level) gas price replacements.
|
||||
if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 {
|
||||
if tx.GasFeeCapUIntLt(thresholdFeeCap) || tx.GasTipCapUIntLt(thresholdTip) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise overwrite the old transaction with the current one
|
||||
l.txs.Put(tx)
|
||||
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
|
||||
|
||||
if cost := tx.CostUint(); l.costcap == nil || l.costcap.Lt(cost) {
|
||||
l.costcap = cost
|
||||
}
|
||||
|
||||
if gas := tx.Gas(); l.gascap < gas {
|
||||
l.gascap = gas
|
||||
}
|
||||
|
||||
return true, old
|
||||
}
|
||||
|
||||
|
|
@ -329,17 +478,20 @@ func (l *txList) Forward(threshold uint64) types.Transactions {
|
|||
// a point in calculating all the costs or if the balance covers all. If the threshold
|
||||
// is lower than the costgas cap, the caps will be reset to a new high after removing
|
||||
// the newly invalidated transactions.
|
||||
func (l *txList) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
|
||||
func (l *txList) Filter(costLimit *uint256.Int, gasLimit uint64) (types.Transactions, types.Transactions) {
|
||||
// If all transactions are below the threshold, short circuit
|
||||
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
||||
if cmath.U256LTE(l.costcap, costLimit) && l.gascap <= gasLimit {
|
||||
return nil, nil
|
||||
}
|
||||
l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds
|
||||
|
||||
l.costcap = costLimit.Clone() // Lower the caps to the thresholds
|
||||
l.gascap = gasLimit
|
||||
|
||||
// Filter out all the transactions above the account's funds
|
||||
cost := uint256.NewInt(0)
|
||||
removed := l.txs.Filter(func(tx *types.Transaction) bool {
|
||||
return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit) > 0
|
||||
cost.SetFromBig(tx.Cost())
|
||||
return tx.Gas() > gasLimit || cost.Gt(costLimit)
|
||||
})
|
||||
|
||||
if len(removed) == 0 {
|
||||
|
|
@ -416,13 +568,18 @@ func (l *txList) LastElement() *types.Transaction {
|
|||
return l.txs.LastElement()
|
||||
}
|
||||
|
||||
func (l *txList) Has(nonce uint64) bool {
|
||||
return l != nil && l.txs.items[nonce] != nil
|
||||
}
|
||||
|
||||
// priceHeap is a heap.Interface implementation over transactions for retrieving
|
||||
// price-sorted transactions to discard when the pool fills up. If baseFee is set
|
||||
// then the heap is sorted based on the effective tip based on the given base fee.
|
||||
// If baseFee is nil then the sorting is based on gasFeeCap.
|
||||
type priceHeap struct {
|
||||
baseFee *big.Int // heap should always be re-sorted after baseFee is changed
|
||||
list []*types.Transaction
|
||||
baseFee *uint256.Int // heap should always be re-sorted after baseFee is changed
|
||||
list []*types.Transaction
|
||||
baseFeeMu sync.RWMutex
|
||||
}
|
||||
|
||||
func (h *priceHeap) Len() int { return len(h.list) }
|
||||
|
|
@ -440,16 +597,24 @@ func (h *priceHeap) Less(i, j int) bool {
|
|||
}
|
||||
|
||||
func (h *priceHeap) cmp(a, b *types.Transaction) int {
|
||||
h.baseFeeMu.RLock()
|
||||
|
||||
if h.baseFee != nil {
|
||||
// Compare effective tips if baseFee is specified
|
||||
if c := a.EffectiveGasTipCmp(b, h.baseFee); c != 0 {
|
||||
if c := a.EffectiveGasTipTxUintCmp(b, h.baseFee); c != 0 {
|
||||
h.baseFeeMu.RUnlock()
|
||||
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
h.baseFeeMu.RUnlock()
|
||||
|
||||
// Compare fee caps if baseFee is not specified or effective tips are equal
|
||||
if c := a.GasFeeCapCmp(b); c != 0 {
|
||||
return c
|
||||
}
|
||||
|
||||
// Compare tips if effective tips and fee caps are equal
|
||||
return a.GasTipCapCmp(b)
|
||||
}
|
||||
|
|
@ -629,7 +794,10 @@ func (l *txPricedList) Reheap() {
|
|||
|
||||
// SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not
|
||||
// necessary to call right before SetBaseFee when processing a new block.
|
||||
func (l *txPricedList) SetBaseFee(baseFee *big.Int) {
|
||||
func (l *txPricedList) SetBaseFee(baseFee *uint256.Int) {
|
||||
l.urgent.baseFeeMu.Lock()
|
||||
l.urgent.baseFee = baseFee
|
||||
l.urgent.baseFeeMu.Unlock()
|
||||
|
||||
l.Reheap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
|
@ -59,11 +60,15 @@ func BenchmarkTxListAdd(b *testing.B) {
|
|||
for i := 0; i < len(txs); i++ {
|
||||
txs[i] = transaction(uint64(i), 0, key)
|
||||
}
|
||||
|
||||
// Insert the transactions in a random order
|
||||
priceLimit := big.NewInt(int64(DefaultTxPoolConfig.PriceLimit))
|
||||
priceLimit := uint256.NewInt(DefaultTxPoolConfig.PriceLimit)
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
list := newTxList(true)
|
||||
|
||||
for _, v := range rand.Perm(len(txs)) {
|
||||
list.Add(txs[v], DefaultTxPoolConfig.PriceBump)
|
||||
list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump)
|
||||
|
|
|
|||
1068
core/tx_pool.go
1068
core/tx_pool.go
File diff suppressed because it is too large
Load diff
1599
core/tx_pool_test.go
1599
core/tx_pool_test.go
File diff suppressed because it is too large
Load diff
|
|
@ -19,6 +19,8 @@ package types
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
|
|
@ -44,15 +46,16 @@ func (al AccessList) StorageKeys() int {
|
|||
|
||||
// AccessListTx is the data of EIP-2930 access list transactions.
|
||||
type AccessListTx struct {
|
||||
ChainID *big.Int // destination chain ID
|
||||
Nonce uint64 // nonce of sender account
|
||||
GasPrice *big.Int // wei per gas
|
||||
Gas uint64 // gas limit
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int // wei amount
|
||||
Data []byte // contract invocation input data
|
||||
AccessList AccessList // EIP-2930 access list
|
||||
V, R, S *big.Int // signature values
|
||||
ChainID *big.Int // destination chain ID
|
||||
Nonce uint64 // nonce of sender account
|
||||
GasPrice *big.Int // wei per gas
|
||||
gasPriceUint256 *uint256.Int // wei per gas
|
||||
Gas uint64 // gas limit
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int // wei amount
|
||||
Data []byte // contract invocation input data
|
||||
AccessList AccessList // EIP-2930 access list
|
||||
V, R, S *big.Int // signature values
|
||||
}
|
||||
|
||||
// copy creates a deep copy of the transaction data and initializes all fields.
|
||||
|
|
@ -80,6 +83,12 @@ func (tx *AccessListTx) copy() TxData {
|
|||
}
|
||||
if tx.GasPrice != nil {
|
||||
cpy.GasPrice.Set(tx.GasPrice)
|
||||
|
||||
if cpy.gasPriceUint256 != nil {
|
||||
cpy.gasPriceUint256.Set(tx.gasPriceUint256)
|
||||
} else {
|
||||
cpy.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
}
|
||||
}
|
||||
if tx.V != nil {
|
||||
cpy.V.Set(tx.V)
|
||||
|
|
@ -100,11 +109,39 @@ func (tx *AccessListTx) accessList() AccessList { return tx.AccessList }
|
|||
func (tx *AccessListTx) data() []byte { return tx.Data }
|
||||
func (tx *AccessListTx) gas() uint64 { return tx.Gas }
|
||||
func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice }
|
||||
func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
||||
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
||||
func (tx *AccessListTx) gasPriceU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *AccessListTx) gasTipCapU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *AccessListTx) gasFeeCapU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
||||
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
||||
|
||||
func (tx *AccessListTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||
return tx.V, tx.R, tx.S
|
||||
|
|
|
|||
|
|
@ -19,19 +19,23 @@ package types
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type DynamicFeeTx struct {
|
||||
ChainID *big.Int
|
||||
Nonce uint64
|
||||
GasTipCap *big.Int // a.k.a. maxPriorityFeePerGas
|
||||
GasFeeCap *big.Int // a.k.a. maxFeePerGas
|
||||
Gas uint64
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int
|
||||
Data []byte
|
||||
AccessList AccessList
|
||||
ChainID *big.Int
|
||||
Nonce uint64
|
||||
GasTipCap *big.Int // a.k.a. maxPriorityFeePerGas
|
||||
gasTipCapUint256 *uint256.Int // a.k.a. maxPriorityFeePerGas
|
||||
GasFeeCap *big.Int // a.k.a. maxFeePerGas
|
||||
gasFeeCapUint256 *uint256.Int // a.k.a. maxFeePerGas
|
||||
Gas uint64
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int
|
||||
Data []byte
|
||||
AccessList AccessList
|
||||
|
||||
// Signature values
|
||||
V *big.Int `json:"v" gencodec:"required"`
|
||||
|
|
@ -65,9 +69,21 @@ func (tx *DynamicFeeTx) copy() TxData {
|
|||
}
|
||||
if tx.GasTipCap != nil {
|
||||
cpy.GasTipCap.Set(tx.GasTipCap)
|
||||
|
||||
if cpy.gasTipCapUint256 != nil {
|
||||
cpy.gasTipCapUint256.Set(tx.gasTipCapUint256)
|
||||
} else {
|
||||
cpy.gasTipCapUint256, _ = uint256.FromBig(tx.GasTipCap)
|
||||
}
|
||||
}
|
||||
if tx.GasFeeCap != nil {
|
||||
cpy.GasFeeCap.Set(tx.GasFeeCap)
|
||||
|
||||
if cpy.gasFeeCapUint256 != nil {
|
||||
cpy.gasFeeCapUint256.Set(tx.gasFeeCapUint256)
|
||||
} else {
|
||||
cpy.gasFeeCapUint256, _ = uint256.FromBig(tx.GasFeeCap)
|
||||
}
|
||||
}
|
||||
if tx.V != nil {
|
||||
cpy.V.Set(tx.V)
|
||||
|
|
@ -88,11 +104,38 @@ func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList }
|
|||
func (tx *DynamicFeeTx) data() []byte { return tx.Data }
|
||||
func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas }
|
||||
func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap }
|
||||
func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap }
|
||||
func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
|
||||
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
||||
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
||||
func (tx *DynamicFeeTx) gasFeeCapU256() *uint256.Int {
|
||||
if tx.gasFeeCapUint256 != nil {
|
||||
return tx.gasFeeCapUint256
|
||||
}
|
||||
|
||||
tx.gasFeeCapUint256, _ = uint256.FromBig(tx.GasFeeCap)
|
||||
|
||||
return tx.gasFeeCapUint256
|
||||
}
|
||||
func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap }
|
||||
func (tx *DynamicFeeTx) gasTipCapU256() *uint256.Int {
|
||||
if tx.gasTipCapUint256 != nil {
|
||||
return tx.gasTipCapUint256
|
||||
}
|
||||
|
||||
tx.gasTipCapUint256, _ = uint256.FromBig(tx.GasTipCap)
|
||||
|
||||
return tx.gasTipCapUint256
|
||||
}
|
||||
func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
|
||||
func (tx *DynamicFeeTx) gasPriceU256() *uint256.Int {
|
||||
if tx.gasFeeCapUint256 != nil {
|
||||
return tx.gasTipCapUint256
|
||||
}
|
||||
|
||||
tx.gasFeeCapUint256, _ = uint256.FromBig(tx.GasFeeCap)
|
||||
|
||||
return tx.gasFeeCapUint256
|
||||
}
|
||||
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
||||
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
||||
|
||||
func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||
return tx.V, tx.R, tx.S
|
||||
|
|
|
|||
|
|
@ -19,18 +19,21 @@ package types
|
|||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
// LegacyTx is the transaction data of regular Ethereum transactions.
|
||||
type LegacyTx struct {
|
||||
Nonce uint64 // nonce of sender account
|
||||
GasPrice *big.Int // wei per gas
|
||||
Gas uint64 // gas limit
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int // wei amount
|
||||
Data []byte // contract invocation input data
|
||||
V, R, S *big.Int // signature values
|
||||
Nonce uint64 // nonce of sender account
|
||||
GasPrice *big.Int // wei per gas
|
||||
gasPriceUint256 *uint256.Int // wei per gas
|
||||
Gas uint64 // gas limit
|
||||
To *common.Address `rlp:"nil"` // nil means contract creation
|
||||
Value *big.Int // wei amount
|
||||
Data []byte // contract invocation input data
|
||||
V, R, S *big.Int // signature values
|
||||
}
|
||||
|
||||
// NewTransaction creates an unsigned legacy transaction.
|
||||
|
|
@ -77,6 +80,12 @@ func (tx *LegacyTx) copy() TxData {
|
|||
}
|
||||
if tx.GasPrice != nil {
|
||||
cpy.GasPrice.Set(tx.GasPrice)
|
||||
|
||||
if cpy.gasPriceUint256 != nil {
|
||||
cpy.gasPriceUint256.Set(tx.gasPriceUint256)
|
||||
} else {
|
||||
cpy.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
}
|
||||
}
|
||||
if tx.V != nil {
|
||||
cpy.V.Set(tx.V)
|
||||
|
|
@ -97,11 +106,38 @@ func (tx *LegacyTx) accessList() AccessList { return nil }
|
|||
func (tx *LegacyTx) data() []byte { return tx.Data }
|
||||
func (tx *LegacyTx) gas() uint64 { return tx.Gas }
|
||||
func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice }
|
||||
func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
||||
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
||||
func (tx *LegacyTx) gasPriceU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *LegacyTx) gasTipCapU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||
func (tx *LegacyTx) gasFeeCapU256() *uint256.Int {
|
||||
if tx.gasPriceUint256 != nil {
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
|
||||
tx.gasPriceUint256, _ = uint256.FromBig(tx.GasPrice)
|
||||
|
||||
return tx.gasPriceUint256
|
||||
}
|
||||
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
||||
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
||||
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
||||
|
||||
func (tx *LegacyTx) rawSignatureValues() (v, r, s *big.Int) {
|
||||
return tx.V, tx.R, tx.S
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -53,9 +55,9 @@ type Transaction struct {
|
|||
time time.Time // Time first seen locally (spam avoidance)
|
||||
|
||||
// caches
|
||||
hash atomic.Value
|
||||
size atomic.Value
|
||||
from atomic.Value
|
||||
hash atomic.Pointer[common.Hash]
|
||||
size atomic.Pointer[common.StorageSize]
|
||||
from atomic.Pointer[sigCache]
|
||||
}
|
||||
|
||||
// NewTx creates a new transaction.
|
||||
|
|
@ -77,8 +79,11 @@ type TxData interface {
|
|||
data() []byte
|
||||
gas() uint64
|
||||
gasPrice() *big.Int
|
||||
gasPriceU256() *uint256.Int
|
||||
gasTipCap() *big.Int
|
||||
gasTipCapU256() *uint256.Int
|
||||
gasFeeCap() *big.Int
|
||||
gasFeeCapU256() *uint256.Int
|
||||
value() *big.Int
|
||||
nonce() uint64
|
||||
to() *common.Address
|
||||
|
|
@ -194,7 +199,8 @@ func (tx *Transaction) setDecoded(inner TxData, size int) {
|
|||
tx.inner = inner
|
||||
tx.time = time.Now()
|
||||
if size > 0 {
|
||||
tx.size.Store(common.StorageSize(size))
|
||||
v := float64(size)
|
||||
tx.size.Store((*common.StorageSize)(&v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,16 +271,23 @@ func (tx *Transaction) AccessList() AccessList { return tx.inner.accessList() }
|
|||
func (tx *Transaction) Gas() uint64 { return tx.inner.gas() }
|
||||
|
||||
// GasPrice returns the gas price of the transaction.
|
||||
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) }
|
||||
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) }
|
||||
func (tx *Transaction) GasPriceRef() *big.Int { return tx.inner.gasPrice() }
|
||||
func (tx *Transaction) GasPriceUint() *uint256.Int { return tx.inner.gasPriceU256() }
|
||||
|
||||
// GasTipCap returns the gasTipCap per gas of the transaction.
|
||||
func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.gasTipCap()) }
|
||||
func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.gasTipCap()) }
|
||||
func (tx *Transaction) GasTipCapRef() *big.Int { return tx.inner.gasTipCap() }
|
||||
func (tx *Transaction) GasTipCapUint() *uint256.Int { return tx.inner.gasTipCapU256() }
|
||||
|
||||
// GasFeeCap returns the fee cap per gas of the transaction.
|
||||
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
|
||||
func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) }
|
||||
func (tx *Transaction) GasFeeCapRef() *big.Int { return tx.inner.gasFeeCap() }
|
||||
func (tx *Transaction) GasFeeCapUint() *uint256.Int { return tx.inner.gasFeeCapU256() }
|
||||
|
||||
// Value returns the ether amount of the transaction.
|
||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
||||
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) }
|
||||
func (tx *Transaction) ValueRef() *big.Int { return tx.inner.value() }
|
||||
|
||||
// Nonce returns the sender account nonce of the transaction.
|
||||
func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() }
|
||||
|
|
@ -287,9 +300,19 @@ func (tx *Transaction) To() *common.Address {
|
|||
|
||||
// Cost returns gas * gasPrice + value.
|
||||
func (tx *Transaction) Cost() *big.Int {
|
||||
total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))
|
||||
total.Add(total, tx.Value())
|
||||
return total
|
||||
gasPrice, _ := uint256.FromBig(tx.GasPriceRef())
|
||||
gasPrice.Mul(gasPrice, uint256.NewInt(tx.Gas()))
|
||||
value, _ := uint256.FromBig(tx.ValueRef())
|
||||
|
||||
return gasPrice.Add(gasPrice, value).ToBig()
|
||||
}
|
||||
|
||||
func (tx *Transaction) CostUint() *uint256.Int {
|
||||
gasPrice, _ := uint256.FromBig(tx.GasPriceRef())
|
||||
gasPrice.Mul(gasPrice, uint256.NewInt(tx.Gas()))
|
||||
value, _ := uint256.FromBig(tx.ValueRef())
|
||||
|
||||
return gasPrice.Add(gasPrice, value)
|
||||
}
|
||||
|
||||
// RawSignatureValues returns the V, R, S signature values of the transaction.
|
||||
|
|
@ -303,11 +326,18 @@ func (tx *Transaction) GasFeeCapCmp(other *Transaction) int {
|
|||
return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap())
|
||||
}
|
||||
|
||||
// GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap.
|
||||
func (tx *Transaction) GasFeeCapIntCmp(other *big.Int) int {
|
||||
return tx.inner.gasFeeCap().Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) GasFeeCapUIntCmp(other *uint256.Int) int {
|
||||
return tx.inner.gasFeeCapU256().Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) GasFeeCapUIntLt(other *uint256.Int) bool {
|
||||
return tx.inner.gasFeeCapU256().Lt(other)
|
||||
}
|
||||
|
||||
// GasTipCapCmp compares the gasTipCap of two transactions.
|
||||
func (tx *Transaction) GasTipCapCmp(other *Transaction) int {
|
||||
return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap())
|
||||
|
|
@ -318,6 +348,14 @@ func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int {
|
|||
return tx.inner.gasTipCap().Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) GasTipCapUIntCmp(other *uint256.Int) int {
|
||||
return tx.inner.gasTipCapU256().Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) GasTipCapUIntLt(other *uint256.Int) bool {
|
||||
return tx.inner.gasTipCapU256().Lt(other)
|
||||
}
|
||||
|
||||
// EffectiveGasTip returns the effective miner gasTipCap for the given base fee.
|
||||
// Note: if the effective gasTipCap is negative, this method returns both error
|
||||
// the actual negative value, _and_ ErrGasFeeCapTooLow
|
||||
|
|
@ -356,10 +394,73 @@ func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) i
|
|||
return tx.EffectiveGasTipValue(baseFee).Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasTipUintCmp(other *uint256.Int, baseFee *uint256.Int) int {
|
||||
if baseFee == nil {
|
||||
return tx.GasTipCapUIntCmp(other)
|
||||
}
|
||||
|
||||
return tx.EffectiveGasTipValueUint(baseFee).Cmp(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasTipUintLt(other *uint256.Int, baseFee *uint256.Int) bool {
|
||||
if baseFee == nil {
|
||||
return tx.GasTipCapUIntLt(other)
|
||||
}
|
||||
|
||||
return tx.EffectiveGasTipValueUint(baseFee).Lt(other)
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasTipTxUintCmp(other *Transaction, baseFee *uint256.Int) int {
|
||||
if baseFee == nil {
|
||||
return tx.inner.gasTipCapU256().Cmp(other.inner.gasTipCapU256())
|
||||
}
|
||||
|
||||
return tx.EffectiveGasTipValueUint(baseFee).Cmp(other.EffectiveGasTipValueUint(baseFee))
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasTipValueUint(baseFee *uint256.Int) *uint256.Int {
|
||||
effectiveTip, _ := tx.EffectiveGasTipUnit(baseFee)
|
||||
return effectiveTip
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasTipUnit(baseFee *uint256.Int) (*uint256.Int, error) {
|
||||
if baseFee == nil {
|
||||
return tx.GasFeeCapUint(), nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
gasFeeCap := tx.GasFeeCapUint().Clone()
|
||||
|
||||
if gasFeeCap.Lt(baseFee) {
|
||||
err = ErrGasFeeCapTooLow
|
||||
}
|
||||
|
||||
gasTipCapUint := tx.GasTipCapUint()
|
||||
|
||||
if gasFeeCap.Lt(gasTipCapUint) {
|
||||
return gasFeeCap, err
|
||||
}
|
||||
|
||||
if gasFeeCap.Lt(gasTipCapUint) && baseFee.IsZero() {
|
||||
return gasFeeCap, err
|
||||
}
|
||||
|
||||
gasFeeCap.Sub(gasFeeCap, baseFee)
|
||||
|
||||
if gasFeeCap.Gt(gasTipCapUint) || gasFeeCap.Eq(gasTipCapUint) {
|
||||
gasFeeCap.Add(gasFeeCap, baseFee)
|
||||
|
||||
return gasTipCapUint, err
|
||||
}
|
||||
|
||||
return gasFeeCap, err
|
||||
}
|
||||
|
||||
// Hash returns the transaction hash.
|
||||
func (tx *Transaction) Hash() common.Hash {
|
||||
if hash := tx.hash.Load(); hash != nil {
|
||||
return hash.(common.Hash)
|
||||
return *hash
|
||||
}
|
||||
|
||||
var h common.Hash
|
||||
|
|
@ -368,7 +469,9 @@ func (tx *Transaction) Hash() common.Hash {
|
|||
} else {
|
||||
h = prefixedRlpHash(tx.Type(), tx.inner)
|
||||
}
|
||||
tx.hash.Store(h)
|
||||
|
||||
tx.hash.Store(&h)
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
|
|
@ -376,11 +479,14 @@ func (tx *Transaction) Hash() common.Hash {
|
|||
// encoding and returning it, or returning a previously cached value.
|
||||
func (tx *Transaction) Size() common.StorageSize {
|
||||
if size := tx.size.Load(); size != nil {
|
||||
return size.(common.StorageSize)
|
||||
return *size
|
||||
}
|
||||
|
||||
c := writeCounter(0)
|
||||
|
||||
rlp.Encode(&c, &tx.inner)
|
||||
tx.size.Store(common.StorageSize(c))
|
||||
tx.size.Store((*common.StorageSize)(&c))
|
||||
|
||||
return common.StorageSize(c)
|
||||
}
|
||||
|
||||
|
|
@ -444,14 +550,14 @@ func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|||
// TxWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
|
||||
type TxWithMinerFee struct {
|
||||
tx *Transaction
|
||||
minerFee *big.Int
|
||||
minerFee *uint256.Int
|
||||
}
|
||||
|
||||
// NewTxWithMinerFee creates a wrapped transaction, calculating the effective
|
||||
// miner gasTipCap if a base fee is provided.
|
||||
// Returns error in case of a negative effective miner gasTipCap.
|
||||
func NewTxWithMinerFee(tx *Transaction, baseFee *big.Int) (*TxWithMinerFee, error) {
|
||||
minerFee, err := tx.EffectiveGasTip(baseFee)
|
||||
func NewTxWithMinerFee(tx *Transaction, baseFee *uint256.Int) (*TxWithMinerFee, error) {
|
||||
minerFee, err := tx.EffectiveGasTipUnit(baseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -496,7 +602,7 @@ type TransactionsByPriceAndNonce struct {
|
|||
txs map[common.Address]Transactions // Per account nonce-sorted list of transactions
|
||||
heads TxByPriceAndTime // Next transaction for each unique account (price heap)
|
||||
signer Signer // Signer for the set of transactions
|
||||
baseFee *big.Int // Current base fee
|
||||
baseFee *uint256.Int // Current base fee
|
||||
}
|
||||
|
||||
// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
||||
|
|
@ -504,6 +610,7 @@ type TransactionsByPriceAndNonce struct {
|
|||
//
|
||||
// Note, the input map is reowned so the caller should not interact any more with
|
||||
// if after providing it to the constructor.
|
||||
/*
|
||||
func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions, baseFee *big.Int) *TransactionsByPriceAndNonce {
|
||||
// Initialize a price and received time based heap with the head transactions
|
||||
heads := make(TxByPriceAndTime, 0, len(txs))
|
||||
|
|
@ -524,6 +631,39 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa
|
|||
}
|
||||
heap.Init(&heads)
|
||||
|
||||
// Assemble and return the transaction set
|
||||
return &TransactionsByPriceAndNonce{
|
||||
txs: txs,
|
||||
heads: heads,
|
||||
signer: signer,
|
||||
baseFee: baseFee,
|
||||
}
|
||||
}*/
|
||||
|
||||
func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions, baseFee *uint256.Int) *TransactionsByPriceAndNonce {
|
||||
// Initialize a price and received time based heap with the head transactions
|
||||
heads := make(TxByPriceAndTime, 0, len(txs))
|
||||
|
||||
for from, accTxs := range txs {
|
||||
if len(accTxs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
acc, _ := Sender(signer, accTxs[0])
|
||||
wrapped, err := NewTxWithMinerFee(accTxs[0], baseFee)
|
||||
|
||||
// Remove transaction if sender doesn't match from, or if wrapping fails.
|
||||
if acc != from || err != nil {
|
||||
delete(txs, from)
|
||||
continue
|
||||
}
|
||||
|
||||
heads = append(heads, wrapped)
|
||||
txs[from] = accTxs[1:]
|
||||
}
|
||||
|
||||
heap.Init(&heads)
|
||||
|
||||
// Assemble and return the transaction set
|
||||
return &TransactionsByPriceAndNonce{
|
||||
txs: txs,
|
||||
|
|
|
|||
|
|
@ -130,12 +130,11 @@ func MustSignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) *Transaction
|
|||
// not match the signer used in the current call.
|
||||
func Sender(signer Signer, tx *Transaction) (common.Address, error) {
|
||||
if sc := tx.from.Load(); sc != nil {
|
||||
sigCache := sc.(sigCache)
|
||||
// If the signer used to derive from in a previous
|
||||
// call is not the same as used current, invalidate
|
||||
// the cache.
|
||||
if sigCache.signer.Equal(signer) {
|
||||
return sigCache.from, nil
|
||||
if sc.signer.Equal(signer) {
|
||||
return sc.from, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +142,9 @@ func Sender(signer Signer, tx *Transaction) (common.Address, error) {
|
|||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
tx.from.Store(sigCache{signer: signer, from: addr})
|
||||
|
||||
tx.from.Store(&sigCache{signer: signer, from: addr})
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
|
|
@ -461,10 +462,10 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *
|
|||
func (fs FrontierSigner) Hash(tx *Transaction) common.Hash {
|
||||
return rlpHash([]interface{}{
|
||||
tx.Nonce(),
|
||||
tx.GasPrice(),
|
||||
tx.GasPriceRef(),
|
||||
tx.Gas(),
|
||||
tx.To(),
|
||||
tx.Value(),
|
||||
tx.ValueRef(),
|
||||
tx.Data(),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
cmath "github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
|
@ -272,14 +275,22 @@ func TestTransactionPriceNonceSort1559(t *testing.T) {
|
|||
// Tests that transactions can be correctly sorted according to their price in
|
||||
// decreasing order, but at the same time with increasing nonces when issued by
|
||||
// the same account.
|
||||
func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
||||
//
|
||||
//nolint:gocognit,thelper
|
||||
func testTransactionPriceNonceSort(t *testing.T, baseFeeBig *big.Int) {
|
||||
// Generate a batch of accounts to start with
|
||||
keys := make([]*ecdsa.PrivateKey, 25)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
}
|
||||
|
||||
signer := LatestSignerForChainID(common.Big1)
|
||||
|
||||
var baseFee *uint256.Int
|
||||
if baseFeeBig != nil {
|
||||
baseFee = cmath.FromBig(baseFeeBig)
|
||||
}
|
||||
|
||||
// Generate a batch of transactions with overlapping values, but shifted nonces
|
||||
groups := map[common.Address]Transactions{}
|
||||
expectedCount := 0
|
||||
|
|
@ -308,7 +319,7 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||
GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))),
|
||||
Data: nil,
|
||||
})
|
||||
if count == 25 && int64(gasFeeCap) < baseFee.Int64() {
|
||||
if count == 25 && uint64(gasFeeCap) < baseFee.Uint64() {
|
||||
count = i
|
||||
}
|
||||
}
|
||||
|
|
@ -341,12 +352,25 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||
t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce())
|
||||
}
|
||||
}
|
||||
|
||||
// If the next tx has different from account, the price must be lower than the current one
|
||||
if i+1 < len(txs) {
|
||||
next := txs[i+1]
|
||||
fromNext, _ := Sender(signer, next)
|
||||
tip, err := txi.EffectiveGasTip(baseFee)
|
||||
nextTip, nextErr := next.EffectiveGasTip(baseFee)
|
||||
tip, err := txi.EffectiveGasTipUnit(baseFee)
|
||||
nextTip, nextErr := next.EffectiveGasTipUnit(baseFee)
|
||||
|
||||
tipBig, _ := txi.EffectiveGasTip(baseFeeBig)
|
||||
nextTipBig, _ := next.EffectiveGasTip(baseFeeBig)
|
||||
|
||||
if tip.Cmp(cmath.FromBig(tipBig)) != 0 {
|
||||
t.Fatalf("EffectiveGasTip incorrect. uint256 %q, big.Int %q, baseFee %q, baseFeeBig %q", tip.String(), tipBig.String(), baseFee.String(), baseFeeBig.String())
|
||||
}
|
||||
|
||||
if nextTip.Cmp(cmath.FromBig(nextTipBig)) != 0 {
|
||||
t.Fatalf("EffectiveGasTip next incorrect. uint256 %q, big.Int %q, baseFee %q, baseFeeBig %q", nextTip.String(), nextTipBig.String(), baseFee.String(), baseFeeBig.String())
|
||||
}
|
||||
|
||||
if err != nil || nextErr != nil {
|
||||
t.Errorf("error calculating effective tip")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,11 +236,18 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
|
|||
}
|
||||
|
||||
func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
|
||||
return b.eth.txPool.AddLocal(signedTx)
|
||||
err := b.eth.txPool.AddLocal(signedTx)
|
||||
if err != nil {
|
||||
if unwrapped := errors.Unwrap(err); unwrapped != nil {
|
||||
return unwrapped
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
|
||||
pending := b.eth.txPool.Pending(false)
|
||||
pending := b.eth.txPool.Pending(context.Background(), false)
|
||||
var txs types.Transactions
|
||||
for _, batch := range pending {
|
||||
txs = append(txs, batch...)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ func newCheckpointVerifier(verifyFn func(ctx context.Context, handler *ethHandle
|
|||
)
|
||||
|
||||
// check if we have the checkpoint blocks
|
||||
//nolint:contextcheck
|
||||
head := handler.ethAPI.BlockNumber()
|
||||
if head < hexutil.Uint64(endBlock) {
|
||||
log.Debug("Head block behind checkpoint block", "head", head, "checkpoint end block", endBlock)
|
||||
|
|
|
|||
|
|
@ -55,11 +55,11 @@ const (
|
|||
|
||||
// txArriveTimeout is the time allowance before an announced transaction is
|
||||
// explicitly requested.
|
||||
txArriveTimeout = 500 * time.Millisecond
|
||||
txArriveTimeout = 100 * time.Millisecond
|
||||
|
||||
// txGatherSlack is the interval used to collate almost-expired announces
|
||||
// with network fetches.
|
||||
txGatherSlack = 100 * time.Millisecond
|
||||
txGatherSlack = 20 * time.Millisecond
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -416,10 +416,20 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty
|
|||
return nil, fmt.Errorf("filter not found")
|
||||
}
|
||||
|
||||
borConfig := api.chainConfig.Bor
|
||||
|
||||
var filter *Filter
|
||||
|
||||
var borLogsFilter *BorBlockLogsFilter
|
||||
|
||||
if f.crit.BlockHash != nil {
|
||||
// Block filter requested, construct a single-shot filter
|
||||
filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics)
|
||||
|
||||
// Block bor filter
|
||||
if api.borLogs {
|
||||
borLogsFilter = NewBorBlockLogsFilter(api.backend, borConfig, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics)
|
||||
}
|
||||
} else {
|
||||
// Convert the RPC block numbers into internal representations
|
||||
begin := rpc.LatestBlockNumber.Int64()
|
||||
|
|
@ -432,12 +442,27 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty
|
|||
}
|
||||
// Construct the range filter
|
||||
filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics)
|
||||
|
||||
if api.borLogs {
|
||||
borLogsFilter = NewBorBlockLogsRangeFilter(api.backend, borConfig, begin, end, f.crit.Addresses, f.crit.Topics)
|
||||
}
|
||||
}
|
||||
// Run the filter and return all the logs
|
||||
logs, err := filter.Logs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if borLogsFilter != nil {
|
||||
// Run the filter and return all the logs
|
||||
borBlockLogs, err := borLogsFilter.Logs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return returnLogs(types.MergeBorLogs(logs, borBlockLogs)), nil
|
||||
}
|
||||
|
||||
return returnLogs(logs), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math"
|
||||
"math/big"
|
||||
|
|
@ -69,7 +70,7 @@ type txPool interface {
|
|||
|
||||
// Pending should return pending transactions.
|
||||
// The slice should be modifiable by the caller.
|
||||
Pending(enforceTips bool) map[common.Address]types.Transactions
|
||||
Pending(ctx context.Context, enforceTips bool) map[common.Address]types.Transactions
|
||||
|
||||
// SubscribeNewTxsEvent should return an event subscription of
|
||||
// NewTxsEvent and send events to the given channel.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"sort"
|
||||
"sync"
|
||||
|
|
@ -92,7 +93,7 @@ func (p *testTxPool) AddRemotes(txs []*types.Transaction) []error {
|
|||
}
|
||||
|
||||
// Pending returns all the transactions known to the pool
|
||||
func (p *testTxPool) Pending(enforceTips bool) map[common.Address]types.Transactions {
|
||||
func (p *testTxPool) Pending(ctx context.Context, enforceTips bool) map[common.Address]types.Transactions {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math/big"
|
||||
"sync/atomic"
|
||||
|
|
@ -44,20 +45,24 @@ func (h *handler) syncTransactions(p *eth.Peer) {
|
|||
//
|
||||
// TODO(karalabe): Figure out if we could get away with random order somehow
|
||||
var txs types.Transactions
|
||||
pending := h.txpool.Pending(false)
|
||||
|
||||
pending := h.txpool.Pending(context.Background(), false)
|
||||
for _, batch := range pending {
|
||||
txs = append(txs, batch...)
|
||||
}
|
||||
|
||||
if len(txs) == 0 {
|
||||
return
|
||||
}
|
||||
// The eth/65 protocol introduces proper transaction announcements, so instead
|
||||
// of dripping transactions across multiple peers, just send the entire list as
|
||||
// an announcement and let the remote side decide what they need (likely nothing).
|
||||
|
||||
hashes := make([]common.Hash, len(txs))
|
||||
for i, tx := range txs {
|
||||
hashes[i] = tx.Hash()
|
||||
}
|
||||
|
||||
p.AsyncSendPooledTransactionHashes(hashes)
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +235,7 @@ func (cs *chainSyncer) modeAndLocalHead() (downloader.SyncMode, *big.Int) {
|
|||
// return downloader.SnapSync, td
|
||||
// }
|
||||
// }
|
||||
// Nope, we're really full syncing
|
||||
// // Nope, we're really full syncing
|
||||
// head := cs.handler.chain.CurrentBlock()
|
||||
// td := cs.handler.chain.GetTd(head.Hash(), head.NumberU64())
|
||||
// return downloader.FullSync, td
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -72,11 +72,11 @@ require (
|
|||
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/text v0.4.0
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
|
||||
golang.org/x/tools v0.1.12
|
||||
gonum.org/v1/gonum v0.11.0
|
||||
google.golang.org/grpc v1.48.0
|
||||
google.golang.org/grpc v1.51.0
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6
|
||||
|
|
@ -146,3 +146,5 @@ require (
|
|||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/Masterminds/goutils => github.com/Masterminds/goutils v1.1.1
|
||||
|
|
|
|||
13
go.sum
13
go.sum
|
|
@ -31,8 +31,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
|||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/JekaMas/go-grpc-net-conn v0.0.0-20220708155319-6aff21f2d13d h1:RO27lgfZF8s9lZ3pWyzc0gCE0RZC+6/PXbRjAa0CNp8=
|
||||
github.com/JekaMas/go-grpc-net-conn v0.0.0-20220708155319-6aff21f2d13d/go.mod h1:romz7UPgSYhfJkKOalzEEyV6sWtt/eAEm0nX2aOrod0=
|
||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
|
|
@ -105,7 +105,6 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
|||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
|
||||
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
|
||||
|
|
@ -149,7 +148,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
|||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
|
|
@ -674,8 +672,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
|
@ -771,8 +770,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
|
|||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
|
||||
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
|
||||
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
|
|
|||
15
integration-tests/bor_health.sh
Normal file
15
integration-tests/bor_health.sh
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
while true
|
||||
do
|
||||
peers=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'admin.peers'")
|
||||
block=$(docker exec bor0 bash -c "bor attach /root/.bor/data/bor.ipc -exec 'eth.blockNumber'")
|
||||
|
||||
if [[ -n "$peers" ]] && [[ -n "$block" ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo $peers
|
||||
echo $block
|
||||
|
|
@ -30,19 +30,24 @@ var mumbaiTestnet = &Chain{
|
|||
LondonBlock: big.NewInt(22640000),
|
||||
Bor: ¶ms.BorConfig{
|
||||
JaipurBlock: big.NewInt(22770000),
|
||||
DelhiBlock: big.NewInt(29638656),
|
||||
Period: map[string]uint64{
|
||||
"0": 2,
|
||||
"25275000": 5,
|
||||
"29638656": 2,
|
||||
},
|
||||
ProducerDelay: map[string]uint64{
|
||||
"0": 6,
|
||||
"0": 6,
|
||||
"29638656": 4,
|
||||
},
|
||||
Sprint: map[string]uint64{
|
||||
"0": 64,
|
||||
"0": 64,
|
||||
"29638656": 16,
|
||||
},
|
||||
BackupMultiplier: map[string]uint64{
|
||||
"0": 2,
|
||||
"25275000": 5,
|
||||
"29638656": 2,
|
||||
},
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
|
|
|
|||
|
|
@ -17,17 +17,21 @@
|
|||
"bor": {
|
||||
"period": {
|
||||
"0": 2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"producerDelay": {
|
||||
"0": 6
|
||||
"0": 6,
|
||||
"29638656": 4
|
||||
},
|
||||
"sprint": {
|
||||
"0": 64
|
||||
"0": 64,
|
||||
"29638656": 16
|
||||
},
|
||||
"backupMultiplier": {
|
||||
"0": 2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"validatorContract": "0x0000000000000000000000000000000000001000",
|
||||
"stateReceiverContract": "0x0000000000000000000000000000000000001001",
|
||||
|
|
@ -43,7 +47,8 @@
|
|||
"burntContract": {
|
||||
"22640000": "0x70bcA57F4579f58670aB2d18Ef16e02C17553C38"
|
||||
},
|
||||
"jaipurBlock": 22770000
|
||||
"jaipurBlock": 22770000,
|
||||
"delhiBlock": 29638656
|
||||
}
|
||||
},
|
||||
"nonce": "0x0",
|
||||
|
|
|
|||
|
|
@ -19,17 +19,21 @@
|
|||
"bor":{
|
||||
"period":{
|
||||
"0":2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"producerDelay":{
|
||||
"0": 6
|
||||
"0": 6,
|
||||
"29638656": 4
|
||||
},
|
||||
"sprint":{
|
||||
"0": 64
|
||||
"0": 64,
|
||||
"29638656": 16
|
||||
},
|
||||
"backupMultiplier":{
|
||||
"0": 2,
|
||||
"25275000": 5
|
||||
"25275000": 5,
|
||||
"29638656": 2
|
||||
},
|
||||
"validatorContract":"0x0000000000000000000000000000000000001000",
|
||||
"stateReceiverContract":"0x0000000000000000000000000000000000001001",
|
||||
|
|
@ -45,7 +49,8 @@
|
|||
"burntContract":{
|
||||
"22640000":"0x70bcA57F4579f58670aB2d18Ef16e02C17553C38"
|
||||
},
|
||||
"jaipurBlock":22770000
|
||||
"jaipurBlock":22770000,
|
||||
"delhiBlock": 29638656
|
||||
}
|
||||
},
|
||||
"nonce":"0x0",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ func (c *Command) MarkDown() string {
|
|||
// Help implements the cli.Command interface
|
||||
func (c *Command) Help() string {
|
||||
return `Usage: bor [options]
|
||||
|
||||
|
||||
Run the Bor server.
|
||||
` + c.Flags().Help()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/fdlimit"
|
||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||
|
|
@ -720,10 +721,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
|
|||
}
|
||||
|
||||
for i, account := range c.Accounts.Unlock {
|
||||
err = ks.Unlock(accounts.Account{Address: common.HexToAddress(account)}, passwords[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not unlock an account %q", account)
|
||||
}
|
||||
unlockAccount(ks, account, i, passwords)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -904,6 +902,75 @@ var (
|
|||
gitDate = "" // Git commit date YYYYMMDD of the release (set via linker flags)
|
||||
)
|
||||
|
||||
// tries unlocking the specified account a few times.
|
||||
func unlockAccount(ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) {
|
||||
account, err := utils.MakeAddress(ks, address)
|
||||
|
||||
if err != nil {
|
||||
utils.Fatalf("Could not list accounts: %v", err)
|
||||
}
|
||||
|
||||
for trials := 0; trials < 3; trials++ {
|
||||
prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3)
|
||||
password := utils.GetPassPhraseWithList(prompt, false, i, passwords)
|
||||
err = ks.Unlock(account, password)
|
||||
|
||||
if err == nil {
|
||||
log.Info("Unlocked account", "address", account.Address.Hex())
|
||||
return account, password
|
||||
}
|
||||
|
||||
if err, ok := err.(*keystore.AmbiguousAddrError); ok {
|
||||
log.Info("Unlocked account", "address", account.Address.Hex())
|
||||
return ambiguousAddrRecovery(ks, err, password), password
|
||||
}
|
||||
|
||||
if err != keystore.ErrDecrypt {
|
||||
// No need to prompt again if the error is not decryption-related.
|
||||
break
|
||||
}
|
||||
}
|
||||
// All trials expended to unlock account, bail out
|
||||
utils.Fatalf("Failed to unlock account %s (%v)", address, err)
|
||||
|
||||
return accounts.Account{}, ""
|
||||
}
|
||||
|
||||
func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account {
|
||||
log.Warn("Multiple key files exist for", "address", err.Addr)
|
||||
|
||||
for _, a := range err.Matches {
|
||||
log.Info("Multiple keys", "file", a.URL.String())
|
||||
}
|
||||
|
||||
log.Info("Testing your password against all of them...")
|
||||
|
||||
var match *accounts.Account
|
||||
|
||||
for _, a := range err.Matches {
|
||||
if err := ks.Unlock(a, auth); err == nil {
|
||||
// nolint: gosec, exportloopref
|
||||
match = &a
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if match == nil {
|
||||
utils.Fatalf("None of the listed files could be unlocked.")
|
||||
}
|
||||
|
||||
log.Info("Your password unlocked", "key", match.URL.String())
|
||||
log.Warn("In order to avoid this warning, you need to remove the following duplicate key files:")
|
||||
|
||||
for _, a := range err.Matches {
|
||||
if a != *match {
|
||||
log.Warn("Duplicate", "key", a.URL.String())
|
||||
}
|
||||
}
|
||||
|
||||
return *match
|
||||
}
|
||||
|
||||
func (c *Config) buildNode() (*node.Config, error) {
|
||||
ipcPath := ""
|
||||
if !c.JsonRPC.IPCDisable {
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ func TestDefaultDatatypeOverride(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigLoadFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
readFile := func(path string) {
|
||||
config, err := readConfigFile(path)
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -124,11 +126,15 @@ func TestConfigLoadFile(t *testing.T) {
|
|||
|
||||
// read file in hcl format
|
||||
t.Run("hcl", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
readFile("./testdata/test.hcl")
|
||||
})
|
||||
|
||||
// read file in json format
|
||||
t.Run("json", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
readFile("./testdata/test.json")
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,28 @@ func CPUProfile(ctx context.Context, sec int) ([]byte, map[string]string, error)
|
|||
}, nil
|
||||
}
|
||||
|
||||
// CPUProfile generates a CPU Profile for a given duration
|
||||
func CPUProfileWithChannel(done chan bool) ([]byte, map[string]string, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := pprof.StartCPUProfile(&buf); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(30 * time.Second):
|
||||
}
|
||||
|
||||
pprof.StopCPUProfile()
|
||||
|
||||
return buf.Bytes(),
|
||||
map[string]string{
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"Content-Type": "application/octet-stream",
|
||||
"Content-Disposition": `attachment; filename="profile"`,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Trace runs a trace profile for a given duration
|
||||
func Trace(ctx context.Context, sec int) ([]byte, map[string]string, error) {
|
||||
if sec <= 0 {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -1615,6 +1616,26 @@ type PublicTransactionPoolAPI struct {
|
|||
signer types.Signer
|
||||
}
|
||||
|
||||
// returns block transactions along with state-sync transaction if present
|
||||
// nolint: unparam
|
||||
func (api *PublicTransactionPoolAPI) getAllBlockTransactions(ctx context.Context, block *types.Block) (types.Transactions, bool) {
|
||||
txs := block.Transactions()
|
||||
|
||||
stateSyncPresent := false
|
||||
|
||||
borReceipt := rawdb.ReadBorReceipt(api.b.ChainDb(), block.Hash(), block.NumberU64())
|
||||
if borReceipt != nil {
|
||||
txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
|
||||
if txHash != (common.Hash{}) {
|
||||
borTx, _, _, _, _ := api.b.GetBorBlockTransactionWithBlockHash(ctx, txHash, block.Hash())
|
||||
txs = append(txs, borTx)
|
||||
stateSyncPresent = true
|
||||
}
|
||||
}
|
||||
|
||||
return txs, stateSyncPresent
|
||||
}
|
||||
|
||||
// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool.
|
||||
func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI {
|
||||
// The signer used by the API should always be the 'latest' known one because we expect
|
||||
|
|
@ -1626,7 +1647,8 @@ func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransa
|
|||
// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
|
||||
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
|
||||
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
|
||||
n := hexutil.Uint(len(block.Transactions()))
|
||||
txs, _ := s.getAllBlockTransactions(ctx, block)
|
||||
n := hexutil.Uint(len(txs))
|
||||
return &n
|
||||
}
|
||||
return nil
|
||||
|
|
@ -1635,7 +1657,8 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.
|
|||
// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
|
||||
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
|
||||
if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil {
|
||||
n := hexutil.Uint(len(block.Transactions()))
|
||||
txs, _ := s.getAllBlockTransactions(ctx, block)
|
||||
n := hexutil.Uint(len(txs))
|
||||
return &n
|
||||
}
|
||||
return nil
|
||||
|
|
@ -2207,6 +2230,21 @@ func (api *PrivateDebugAPI) PurgeCheckpointWhitelist() {
|
|||
api.b.PurgeCheckpointWhitelist()
|
||||
}
|
||||
|
||||
// GetTraceStack returns the current trace stack
|
||||
func (api *PrivateDebugAPI) GetTraceStack() string {
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
for {
|
||||
n := runtime.Stack(buf, true)
|
||||
|
||||
if n < len(buf) {
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
buf = make([]byte, 2*len(buf))
|
||||
}
|
||||
}
|
||||
|
||||
// PublicNetAPI offers network related RPC methods
|
||||
type PublicNetAPI struct {
|
||||
net *p2p.Server
|
||||
|
|
|
|||
|
|
@ -484,6 +484,11 @@ web3._extend({
|
|||
call: 'debug_purgeCheckpointWhitelist',
|
||||
params: 0,
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'getTraceStack',
|
||||
call: 'debug_getTraceStack',
|
||||
params: 0,
|
||||
}),
|
||||
],
|
||||
properties: []
|
||||
});
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ func testTransactionStatus(t *testing.T, protocol int) {
|
|||
sendRequest(rawPeer.app, GetTxStatusMsg, reqID, []common.Hash{tx.Hash()})
|
||||
}
|
||||
if err := expectResponse(rawPeer.app, TxStatusMsg, reqID, testBufLimit, []light.TxStatus{expStatus}); err != nil {
|
||||
t.Errorf("transaction status mismatch")
|
||||
t.Error("transaction status mismatch", err)
|
||||
}
|
||||
}
|
||||
signer := types.HomesteadSigner{}
|
||||
|
|
|
|||
|
|
@ -507,25 +507,39 @@ func handleSendTx(msg Decoder) (serveRequestFn, uint64, uint64, error) {
|
|||
if err := msg.Decode(&r); err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
amount := uint64(len(r.Txs))
|
||||
|
||||
return func(backend serverBackend, p *clientPeer, waitOrStop func() bool) *reply {
|
||||
stats := make([]light.TxStatus, len(r.Txs))
|
||||
|
||||
var (
|
||||
err error
|
||||
addFn func(transaction *types.Transaction) error
|
||||
)
|
||||
|
||||
for i, tx := range r.Txs {
|
||||
if i != 0 && !waitOrStop() {
|
||||
return nil
|
||||
}
|
||||
|
||||
hash := tx.Hash()
|
||||
stats[i] = txStatus(backend, hash)
|
||||
|
||||
if stats[i].Status == core.TxStatusUnknown {
|
||||
addFn := backend.TxPool().AddRemotes
|
||||
addFn = backend.TxPool().AddRemote
|
||||
|
||||
// Add txs synchronously for testing purpose
|
||||
if backend.AddTxsSync() {
|
||||
addFn = backend.TxPool().AddRemotesSync
|
||||
addFn = backend.TxPool().AddRemoteSync
|
||||
}
|
||||
if errs := addFn([]*types.Transaction{tx}); errs[0] != nil {
|
||||
stats[i].Error = errs[0].Error()
|
||||
|
||||
if err = addFn(tx); err != nil {
|
||||
stats[i].Error = err.Error()
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
stats[i] = txStatus(backend, hash)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
|
|
@ -71,7 +74,13 @@ func init() {
|
|||
func updateMetricsFromConfig(path string) {
|
||||
// Don't act upon any errors here. They're already taken into
|
||||
// consideration when the toml config file will be parsed in the cli.
|
||||
data, err := os.ReadFile(path)
|
||||
canonicalPath, err := common.VerifyPath(path)
|
||||
if err != nil {
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(canonicalPath)
|
||||
tomlData := string(data)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
211
miner/worker.go
211
miner/worker.go
|
|
@ -17,10 +17,15 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
ptrace "runtime/trace"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
|
@ -31,6 +36,7 @@ import (
|
|||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
cmath "github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/common/tracing"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
|
|
@ -40,6 +46,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
|
@ -88,6 +95,12 @@ const (
|
|||
EnableMVHashMap = true
|
||||
)
|
||||
|
||||
// metrics gauge to track total and empty blocks sealed by a miner
|
||||
var (
|
||||
sealedBlocksCounter = metrics.NewRegisteredCounter("worker/sealedBlocks", nil)
|
||||
sealedEmptyBlocksCounter = metrics.NewRegisteredCounter("worker/sealedEmptyBlocks", nil)
|
||||
)
|
||||
|
||||
// environment is the worker's current environment and holds all
|
||||
// information of the sealing block generation.
|
||||
type environment struct {
|
||||
|
|
@ -262,6 +275,8 @@ type worker struct {
|
|||
skipSealHook func(*task) bool // Method to decide whether skipping the sealing.
|
||||
fullTaskHook func() // Method to call before pushing the full sealing task.
|
||||
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.
|
||||
|
||||
profileCount *int32 // Global count for profiling
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
|
|
@ -290,6 +305,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
resubmitIntervalCh: make(chan time.Duration),
|
||||
resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),
|
||||
}
|
||||
worker.profileCount = new(int32)
|
||||
// Subscribe NewTxsEvent for tx pool
|
||||
worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh)
|
||||
// Subscribe events for blockchain
|
||||
|
|
@ -565,9 +581,11 @@ func (w *worker) mainLoop(ctx context.Context) {
|
|||
for {
|
||||
select {
|
||||
case req := <-w.newWorkCh:
|
||||
//nolint:contextcheck
|
||||
w.commitWork(req.ctx, req.interrupt, req.noempty, req.timestamp)
|
||||
|
||||
case req := <-w.getWorkCh:
|
||||
//nolint:contextcheck
|
||||
block, err := w.generateWork(req.ctx, req.params)
|
||||
if err != nil {
|
||||
req.err = err
|
||||
|
|
@ -627,13 +645,17 @@ func (w *worker) mainLoop(ctx context.Context) {
|
|||
if gp := w.current.gasPool; gp != nil && gp.Gas() < params.TxGas {
|
||||
continue
|
||||
}
|
||||
|
||||
txs := make(map[common.Address]types.Transactions)
|
||||
|
||||
for _, tx := range ev.Txs {
|
||||
acc, _ := types.Sender(w.current.signer, tx)
|
||||
txs[acc] = append(txs[acc], tx)
|
||||
}
|
||||
txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
|
||||
|
||||
txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs, cmath.FromBig(w.current.header.BaseFee))
|
||||
tcount := w.current.tcount
|
||||
|
||||
w.commitTransactions(w.current, txset, nil)
|
||||
|
||||
// Only update the snapshot if any new transactions were added
|
||||
|
|
@ -763,7 +785,7 @@ func (w *worker) resultLoop() {
|
|||
err error
|
||||
)
|
||||
|
||||
tracing.Exec(task.ctx, "resultLoop", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(task.ctx, "", "resultLoop", func(ctx context.Context, span trace.Span) {
|
||||
for i, taskReceipt := range task.receipts {
|
||||
receipt := new(types.Receipt)
|
||||
receipts[i] = receipt
|
||||
|
|
@ -813,6 +835,12 @@ func (w *worker) resultLoop() {
|
|||
// Broadcast the block and announce chain insertion event
|
||||
w.mux.Post(core.NewMinedBlockEvent{Block: block})
|
||||
|
||||
sealedBlocksCounter.Inc(1)
|
||||
|
||||
if block.Transactions().Len() == 0 {
|
||||
sealedEmptyBlocksCounter.Inc(1)
|
||||
}
|
||||
|
||||
// Insert the block into the set of pending ones to resultLoop for confirmations
|
||||
w.unconfirmed.Insert(block.NumberU64(), block.Hash())
|
||||
case <-w.exitCh:
|
||||
|
|
@ -962,6 +990,20 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
|
|||
}(chDeps)
|
||||
}
|
||||
|
||||
initialGasLimit := env.gasPool.Gas()
|
||||
initialTxs := txs.GetTxs()
|
||||
|
||||
var breakCause string
|
||||
|
||||
defer func() {
|
||||
log.Warn("commitTransactions-stats",
|
||||
"initialTxsCount", initialTxs,
|
||||
"initialGasLimit", initialGasLimit,
|
||||
"resultTxsCount", txs.GetTxs(),
|
||||
"resultGapPool", env.gasPool.Gas(),
|
||||
"exitCause", breakCause)
|
||||
}()
|
||||
|
||||
for {
|
||||
if EnableMVHashMap {
|
||||
env.state.AddEmptyMVHashMap()
|
||||
|
|
@ -985,16 +1027,21 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
|
|||
inc: true,
|
||||
}
|
||||
}
|
||||
|
||||
breakCause = "interrupt"
|
||||
return atomic.LoadInt32(interrupt) == commitInterruptNewHead
|
||||
}
|
||||
// If we don't have enough gas for any further transactions then we're done
|
||||
if env.gasPool.Gas() < params.TxGas {
|
||||
log.Trace("Not enough gas for further transactions", "have", env.gasPool, "want", params.TxGas)
|
||||
|
||||
breakCause = "Not enough gas for further transactions"
|
||||
break
|
||||
}
|
||||
// Retrieve the next transaction and abort if all done
|
||||
tx := txs.Peek()
|
||||
if tx == nil {
|
||||
breakCause = "all transactions has been included"
|
||||
break
|
||||
}
|
||||
// Error may be ignored here. The error has already been checked
|
||||
|
|
@ -1013,7 +1060,10 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
|
|||
// Start executing the transaction
|
||||
env.state.Prepare(tx.Hash(), env.tcount)
|
||||
|
||||
start := time.Now()
|
||||
|
||||
logs, err := w.commitTransaction(env, tx)
|
||||
|
||||
switch {
|
||||
case errors.Is(err, core.ErrGasLimitReached):
|
||||
// Pop the current out-of-gas transaction without shifting in the next from the account
|
||||
|
|
@ -1050,6 +1100,7 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
|
|||
count++
|
||||
|
||||
txs.Shift()
|
||||
log.Info("Committed new tx", "tx hash", tx.Hash(), "from", from, "to", tx.To(), "nonce", tx.Nonce(), "gas", tx.Gas(), "gasPrice", tx.GasPrice(), "value", tx.Value(), "time spent", time.Since(start))
|
||||
}
|
||||
|
||||
case errors.Is(err, core.ErrTxTypeNotSupported):
|
||||
|
|
@ -1189,7 +1240,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||
}
|
||||
// Set baseFee and GasLimit if we are on an EIP-1559 chain
|
||||
if w.chainConfig.IsLondon(header.Number) {
|
||||
header.BaseFee = misc.CalcBaseFee(w.chainConfig, parent.Header())
|
||||
header.BaseFee = misc.CalcBaseFeeUint(w.chainConfig, parent.Header()).ToBig()
|
||||
if !w.chainConfig.IsLondon(parent.Number()) {
|
||||
parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
|
||||
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
|
||||
|
|
@ -1229,9 +1280,75 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
|
|||
return env, nil
|
||||
}
|
||||
|
||||
func startProfiler(profile string, filepath string, number uint64) (func() error, error) {
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
err error
|
||||
)
|
||||
|
||||
closeFn := func() {}
|
||||
|
||||
switch profile {
|
||||
case "cpu":
|
||||
err = pprof.StartCPUProfile(&buf)
|
||||
|
||||
if err == nil {
|
||||
closeFn = func() {
|
||||
pprof.StopCPUProfile()
|
||||
}
|
||||
}
|
||||
case "trace":
|
||||
err = ptrace.Start(&buf)
|
||||
|
||||
if err == nil {
|
||||
closeFn = func() {
|
||||
ptrace.Stop()
|
||||
}
|
||||
}
|
||||
case "heap":
|
||||
runtime.GC()
|
||||
|
||||
err = pprof.WriteHeapProfile(&buf)
|
||||
default:
|
||||
log.Info("Incorrect profile name")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return func() error {
|
||||
closeFn()
|
||||
return nil
|
||||
}, err
|
||||
}
|
||||
|
||||
closeFnNew := func() error {
|
||||
var err error
|
||||
|
||||
closeFn()
|
||||
|
||||
if buf.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath + "/" + profile + "-" + fmt.Sprint(number) + ".prof")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Write(buf.Bytes())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return closeFnNew, nil
|
||||
}
|
||||
|
||||
// fillTransactions retrieves the pending transactions from the txpool and fills them
|
||||
// into the given sealing block. The transaction selection and ordering strategy can
|
||||
// be customized with the plugin in the future.
|
||||
//
|
||||
//nolint:gocognit
|
||||
func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) {
|
||||
ctx, span := tracing.StartSpan(ctx, "fillTransactions")
|
||||
defer tracing.EndSpan(span)
|
||||
|
|
@ -1246,10 +1363,76 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
remoteTxs map[common.Address]types.Transactions
|
||||
)
|
||||
|
||||
tracing.Exec(ctx, "worker.SplittingTransactions", func(ctx context.Context, span trace.Span) {
|
||||
pending := w.eth.TxPool().Pending(true)
|
||||
// TODO: move to config or RPC
|
||||
const profiling = false
|
||||
|
||||
if profiling {
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
defer func() {
|
||||
close(doneCh)
|
||||
}()
|
||||
|
||||
go func(number uint64) {
|
||||
closeFn := func() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-time.After(150 * time.Millisecond):
|
||||
// Check if we've not crossed limit
|
||||
if attempt := atomic.AddInt32(w.profileCount, 1); attempt >= 10 {
|
||||
log.Info("Completed profiling", "attempt", attempt)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("Starting profiling in fill transactions", "number", number)
|
||||
|
||||
dir, err := os.MkdirTemp("", fmt.Sprintf("bor-traces-%s-", time.Now().UTC().Format("2006-01-02-150405Z")))
|
||||
if err != nil {
|
||||
log.Error("Error in profiling", "path", dir, "number", number, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
// grab the cpu profile
|
||||
closeFnInternal, err := startProfiler("cpu", dir, number)
|
||||
if err != nil {
|
||||
log.Error("Error in profiling", "path", dir, "number", number, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
closeFn = func() error {
|
||||
err := closeFnInternal()
|
||||
|
||||
log.Info("Completed profiling", "path", dir, "number", number, "error", err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
case <-doneCh:
|
||||
err := closeFn()
|
||||
|
||||
if err != nil {
|
||||
log.Info("closing fillTransactions", "number", number, "error", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}(env.header.Number.Uint64())
|
||||
}
|
||||
|
||||
tracing.Exec(ctx, "", "worker.SplittingTransactions", func(ctx context.Context, span trace.Span) {
|
||||
|
||||
prePendingTime := time.Now()
|
||||
|
||||
pending := w.eth.TxPool().Pending(ctx, true)
|
||||
remoteTxs = pending
|
||||
|
||||
postPendingTime := time.Now()
|
||||
|
||||
for _, account := range w.eth.TxPool().Locals() {
|
||||
if txs := remoteTxs[account]; len(txs) > 0 {
|
||||
delete(remoteTxs, account)
|
||||
|
|
@ -1257,6 +1440,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
}
|
||||
}
|
||||
|
||||
postLocalsTime := time.Now()
|
||||
|
||||
localTxsCount = len(localTxs)
|
||||
remoteTxsCount = len(remoteTxs)
|
||||
|
||||
|
|
@ -1264,6 +1449,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
span,
|
||||
attribute.Int("len of local txs", localTxsCount),
|
||||
attribute.Int("len of remote txs", remoteTxsCount),
|
||||
attribute.String("time taken by Pending()", fmt.Sprintf("%v", postPendingTime.Sub(prePendingTime))),
|
||||
attribute.String("time taken by Locals()", fmt.Sprintf("%v", postLocalsTime.Sub(postPendingTime))),
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -1276,8 +1463,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
if localTxsCount > 0 {
|
||||
var txs *types.TransactionsByPriceAndNonce
|
||||
|
||||
tracing.Exec(ctx, "worker.LocalTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
|
||||
tracing.Exec(ctx, "", "worker.LocalTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, cmath.FromBig(env.header.BaseFee))
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
|
|
@ -1285,7 +1472,7 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
)
|
||||
})
|
||||
|
||||
tracing.Exec(ctx, "worker.LocalCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(ctx, "", "worker.LocalCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
committed = w.commitTransactions(env, txs, interrupt)
|
||||
})
|
||||
|
||||
|
|
@ -1299,8 +1486,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
if remoteTxsCount > 0 {
|
||||
var txs *types.TransactionsByPriceAndNonce
|
||||
|
||||
tracing.Exec(ctx, "worker.RemoteTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
|
||||
tracing.Exec(ctx, "", "worker.RemoteTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) {
|
||||
txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, cmath.FromBig(env.header.BaseFee))
|
||||
|
||||
tracing.SetAttributes(
|
||||
span,
|
||||
|
|
@ -1308,7 +1495,7 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en
|
|||
)
|
||||
})
|
||||
|
||||
tracing.Exec(ctx, "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(ctx, "", "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) {
|
||||
committed = w.commitTransactions(env, txs, interrupt)
|
||||
})
|
||||
|
||||
|
|
@ -1349,7 +1536,7 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool,
|
|||
err error
|
||||
)
|
||||
|
||||
tracing.Exec(ctx, "worker.prepareWork", func(ctx context.Context, span trace.Span) {
|
||||
tracing.Exec(ctx, "", "worker.prepareWork", func(ctx context.Context, span trace.Span) {
|
||||
// Set the coinbase if the worker is running or it's required
|
||||
var coinbase common.Address
|
||||
if w.isRunning() {
|
||||
|
|
|
|||
|
|
@ -350,19 +350,24 @@ var (
|
|||
LondonBlock: big.NewInt(22640000),
|
||||
Bor: &BorConfig{
|
||||
JaipurBlock: big.NewInt(22770000),
|
||||
DelhiBlock: big.NewInt(29638656),
|
||||
Period: map[string]uint64{
|
||||
"0": 2,
|
||||
"25275000": 5,
|
||||
"29638656": 2,
|
||||
},
|
||||
ProducerDelay: map[string]uint64{
|
||||
"0": 6,
|
||||
"0": 6,
|
||||
"29638656": 4,
|
||||
},
|
||||
Sprint: map[string]uint64{
|
||||
"0": 64,
|
||||
"0": 64,
|
||||
"29638656": 16,
|
||||
},
|
||||
BackupMultiplier: map[string]uint64{
|
||||
"0": 2,
|
||||
"25275000": 5,
|
||||
"29638656": 2,
|
||||
},
|
||||
ValidatorContract: "0x0000000000000000000000000000000000001000",
|
||||
StateReceiverContract: "0x0000000000000000000000000000000000001001",
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
VersionMajor = 0 // Major version component of the current release
|
||||
VersionMinor = 3 // Minor version component of the current release
|
||||
VersionPatch = 1 // Patch version component of the current release
|
||||
VersionMeta = "beta" // Version metadata to append to the version string
|
||||
VersionMajor = 0 // Major version component of the current release
|
||||
VersionMinor = 3 // Minor version component of the current release
|
||||
VersionPatch = 1 // Patch version component of the current release
|
||||
VersionMeta = "mumbai" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
// Version holds the textual version string.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import (
|
|||
"os"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const pathOfPackageRLP = "github.com/ethereum/go-ethereum/rlp"
|
||||
|
|
@ -52,8 +54,15 @@ func main() {
|
|||
}
|
||||
if *output == "-" {
|
||||
os.Stdout.Write(code)
|
||||
} else if err := ioutil.WriteFile(*output, code, 0644); err != nil {
|
||||
fatal(err)
|
||||
} else {
|
||||
canonicalPath, err := common.VerifyPath(*output)
|
||||
if err != nil {
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(canonicalPath, code, 0600); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/pelletier/go-toml"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/internal/cli/server"
|
||||
)
|
||||
|
||||
|
|
@ -514,7 +515,13 @@ func commentFlags(path string, updatedArgs []string) {
|
|||
|
||||
ignoreLineFlag := false
|
||||
|
||||
input, err := os.ReadFile(path)
|
||||
canonicalPath, err := common.VerifyPath(path)
|
||||
if err != nil {
|
||||
fmt.Println("path not verified: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
input, err := os.ReadFile(canonicalPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
|
@ -594,7 +601,7 @@ func commentFlags(path string, updatedArgs []string) {
|
|||
|
||||
output := strings.Join(newLines, "\n")
|
||||
|
||||
err = os.WriteFile(path, []byte(output), 0600)
|
||||
err = os.WriteFile(canonicalPath, []byte(output), 0600)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/difficulty"
|
||||
)
|
||||
|
||||
|
|
@ -14,10 +14,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
difficulty.Fuzz(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/les"
|
||||
)
|
||||
|
||||
|
|
@ -32,10 +32,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
les.Fuzz(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/rangeproof"
|
||||
)
|
||||
|
||||
|
|
@ -32,10 +32,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
rangeproof.Fuzz(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/snap"
|
||||
)
|
||||
|
||||
|
|
@ -30,10 +30,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
snap.FuzzTrieNodes(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/stacktrie"
|
||||
)
|
||||
|
||||
|
|
@ -14,10 +14,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
stacktrie.Debug(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/vflux"
|
||||
)
|
||||
|
|
@ -35,10 +35,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := ioutil.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
|
||||
data := common.VerifyCrasher(crasher)
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
vflux.FuzzClientPool(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,9 +141,6 @@ func (tm *testMatcher) findSkip(name string) (reason string, skipload bool) {
|
|||
isWin32 := runtime.GOARCH == "386" && runtime.GOOS == "windows"
|
||||
for _, re := range tm.slowpat {
|
||||
if re.MatchString(name) {
|
||||
if testing.Short() {
|
||||
return "skipped in -short mode", false
|
||||
}
|
||||
if isWin32 {
|
||||
return "skipped on 32bit windows", false
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue