Merge branch 'develop' into manav/upstream_merge_v1.14.11

This commit is contained in:
Manav Darji 2025-03-20 18:31:15 +05:30
commit 754cce0629
No known key found for this signature in database
GPG key ID: A426F0124435F36E
54 changed files with 518 additions and 403 deletions

View file

@ -20,7 +20,7 @@ Heimdall client version: [e.g. v0.2.10] <!--Can be found by running the command
OS & Version: Windows / Linux / OSX
Environment: Polygon Mainnet / Polygon Mumbai / Polygon Amoy / Devnet
Environment: Polygon Mainnet / Polygon Amoy / Devnet
Type of node: Validator / Sentry / Archive

View file

@ -1,26 +1,38 @@
defaultStake: 10000
devnetType: docker
defaultFee: 2000
defaultStake: 10000
borChainId: 15001
heimdallChainId: heimdall-15001
contractsBranch: mardizzone/node-16
borDockerBuildContext: '../../bor'
heimdallDockerBuildContext: 'https://github.com/maticnetwork/heimdall.git#develop'
genesisContractsBranch: master
sprintSize:
- '64'
blockNumber:
- '0'
contractsRepo: https://github.com/0xPolygon/pos-contracts.git
contractsBranch: anvil-pos
blockTime:
- '2'
blockNumber:
- '0'
sprintSize:
- '64'
sprintSizeBlockNumber:
- '0'
numOfBorValidators: 3
numOfBorSentries: 0
numOfBorArchiveNodes: 0
devnetBorFlags: config,config,config
numOfErigonValidators: 0
numOfErigonSentries: 0
numOfErigonArchiveNodes: 0
ethURL: http://ganache:9545
ethURL: http://anvil:9545
ethHostUser: ubuntu
devnetType: docker
borDockerBuildContext: "../../bor"
heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#develop"
sprintSizeBlockNumber:
- '0'
devnetBorFlags: config,config,config
mnemonic: 'clock radar mass judge dismiss just intact mind resemble fringe diary casino'

View file

@ -1,7 +1,7 @@
# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 30
# Label requiring a response
responseRequiredLabel: "need:more-information"
responseRequiredLabel: 'need:more-information'
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response

View file

@ -39,7 +39,7 @@ In case this PR includes changes that must be applied only to a subset of nodes,
- [ ] I have added tests to CI
- [ ] I have tested this code manually on local environment
- [ ] I have tested this code manually on remote devnet using express-cli
- [ ] I have tested this code manually on mumbai/amoy
- [ ] I have tested this code manually on amoy
- [ ] I have created new e2e tests into express-cli
### Manual tests

2
.github/stale.yml vendored
View file

@ -7,7 +7,7 @@ exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: "status:inactive"
staleLabel: 'status:inactive'
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had

View file

@ -29,7 +29,6 @@ jobs:
NUMERIC_VERSION=$( echo ${{ env.GIT_TAG }} | sed 's/[^0-9.]//g' )
echo "VERSION=$NUMERIC_VERSION" >> $GITHUB_ENV
- name: Making directory structure for yaml
run: mkdir -p packaging/deb/bor/var/lib/bor
- name: making directory structure for the systemd
@ -391,14 +390,3 @@ jobs:
packaging/deb/bor-pbss-amoy-**.deb
packaging/deb/bor-amoy-**.deb.checksum
packaging/deb/bor-pbss-amoy-**.deb.checksum

View file

@ -2,12 +2,12 @@ name: CI
on:
push:
branches:
- "master"
- "qa"
- "develop"
- 'master'
- 'qa'
- 'develop'
pull_request:
branches:
- "**"
- '**'
types: [opened, synchronize]
concurrency:
@ -16,11 +16,14 @@ concurrency:
jobs:
build:
name: Build
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- run: |
@ -51,7 +54,7 @@ jobs:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -79,7 +82,7 @@ jobs:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -130,7 +133,7 @@ jobs:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -167,7 +170,7 @@ jobs:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
needs: [unit-tests, integration-tests]
steps:
@ -182,7 +185,7 @@ jobs:
if: (github.event.action != 'closed' || github.event.pull_request.merged == true)
strategy:
matrix:
os: [ ubuntu-22.04 ] # list of os: https://github.com/actions/virtual-environments
os: [ubuntu-22.04] # List of OS: https://github.com/actions/virtual-environments
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@ -211,9 +214,7 @@ jobs:
sudo apt update
sudo apt install build-essential
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
sudo snap install solc
sudo apt install python2 jq curl
sudo ln -sf /usr/bin/python2 /usr/bin/python
sudo apt install jq curl
- uses: actions/setup-node@v3
with:
@ -225,6 +226,23 @@ jobs:
matic-cli/devnet/code/genesis-contracts/package-lock.json
matic-cli/devnet/code/genesis-contracts/matic-contracts/package-lock.json
- name: Install solc-select
run: |
sudo apt update
sudo apt install python3 python3-pip -y
sudo ln -sf /usr/bin/python3 /usr/bin/python
pip install solc-select
- name: Install Solidity Version
run: |
solc-select install 0.5.17
solc-select install 0.6.12
solc-select use 0.5.17
solc --version
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Bootstrap devnet
run: |
cd matic-cli
@ -242,12 +260,14 @@ jobs:
- name: Run smoke tests
run: |
echo "Funding ganache accounts..."
timeout 10m bash bor/integration-tests/fund_ganache_accounts.sh
echo "Deposit 100 matic for each account to bor network"
cd matic-cli/devnet/code/contracts
npm run truffle exec scripts/deposit.js -- --network development $(jq -r .root.tokens.MaticToken contractAddresses.json) 100000000000000000000
cd -
cd matic-cli/devnet/devnet
SCRIPT_ADDRESS=$(jq -r '.[0].address' signer-dump.json)
SCRIPT_PRIVATE_KEY=$(jq -r '.[0].priv_key' signer-dump.json)
cd ../code/pos-contracts
CONTRACT_ADDRESS=$(jq -r .root.tokens.MaticToken contractAddresses.json)
forge script scripts/matic-cli-scripts/Deposit.s.sol:MaticDeposit --rpc-url http://localhost:9545 --private-key $SCRIPT_PRIVATE_KEY --broadcast --sig "run(address,address,uint256)" $SCRIPT_ADDRESS $CONTRACT_ADDRESS 100000000000000000000
cd ../../../..
timeout 60m bash bor/integration-tests/smoke_test.sh
- name: Run RPC Tests

View file

@ -1,10 +1,10 @@
name: "CodeQL"
name: 'CodeQL'
on:
push:
branches: [ "master", "develop" ]
branches: ['master', 'develop']
pull_request:
branches: [ "master", "develop" ]
branches: ['master', 'develop']
schedule:
- cron: '0 0 * * *'
@ -43,4 +43,4 @@ jobs:
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
category: '/language:${{matrix.language}}'

View file

@ -8,7 +8,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
go-version: "1.23.6"
go-version: '1.23.6'
check-latest: true
- uses: actions/checkout@v4
- uses: technote-space/get-diff-action@v6
@ -20,4 +20,4 @@ jobs:
Makefile
- name: govulncheck
run: make vulncheck
if: "env.GIT_DIFF != ''"
if: env.GIT_DIFF != ''

View file

@ -29,7 +29,6 @@ jobs:
NUMERIC_VERSION=$( echo ${{ env.GIT_TAG }} | sed 's/[^0-9.]//g' )
echo "VERSION=$NUMERIC_VERSION" >> $GITHUB_ENV
- name: Making directory structure for yaml
run: mkdir -p packaging/deb/bor/var/lib/bor
- name: making directory structure for the systemd
@ -387,8 +386,6 @@ jobs:
NODE: archive
NETWORK: mainnet
############ Check and Upload ##########################
- name: Confirming package built
run: ls -ltr packaging/deb/ | grep bor

View file

@ -97,7 +97,6 @@ jobs:
echo "Maintainer: devops@polygon.technology" >> packaging/deb/bor/DEBIAN/control
echo "Description: bor binary package" >> packaging/deb/bor/DEBIAN/control
- name: Creating package for binary for bor ${{ env.ARCH }}
run: cp -rp packaging/deb/bor packaging/deb/bor-${{ env.GIT_TAG }}-${{ env.ARCH }}
env:

View file

@ -11,7 +11,6 @@ on:
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write

View file

@ -90,7 +90,6 @@ lintci-deps:
vulncheck:
@go run golang.org/x/vuln/cmd/govulncheck@latest ./...
goimports:
goimports -local "$(PACKAGE)" -w .

View file

@ -1,9 +1,7 @@
# Bor Overview
Bor is the Official Golang implementation of the Polygon PoS blockchain. It is a fork of [geth](https://github.com/ethereum/go-ethereum) and is EVM compatible (upto London fork).
Bor is the official Golang implementation of the Polygon PoS blockchain. It is a fork of [geth](https://github.com/ethereum/go-ethereum) and is EVM compatible (upto London fork).
[![API Reference](
https://pkg.go.dev/badge/github.com/maticnetwork/bor
)](https://pkg.go.dev/github.com/maticnetwork/bor)
[![API Reference](https://pkg.go.dev/badge/github.com/maticnetwork/bor)](https://pkg.go.dev/github.com/maticnetwork/bor)
[![Go Report Card](https://goreportcard.com/badge/github.com/maticnetwork/bor)](https://goreportcard.com/report/github.com/maticnetwork/bor)
![MIT License](https://img.shields.io/github/license/maticnetwork/bor)
[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.com/invite/0xpolygonrnd)
@ -13,15 +11,15 @@ https://pkg.go.dev/badge/github.com/maticnetwork/bor
The easiest way to get started with bor is to install the packages using the command below. Please take a look at the [releases](https://github.com/maticnetwork/bor/releases) section to find the latest stable version of bor.
curl -L https://raw.githubusercontent.com/maticnetwork/install/main/bor.sh | bash -s -- v0.4.0 <network> <node_type>
curl -L https://raw.githubusercontent.com/maticnetwork/install/main/bor.sh | bash -s -- v2.0.0 <network> <node_type>
The network accepts `mainnet`,`amoy` or `mumbai` and the node type accepts `validator` or `sentry` or `archive`. The installation script does the following things:
The network accepts `mainnet`, or `amoy` and the node type accepts `validator` or `sentry` or `archive`. The installation script does the following things:
- Create a new user named `bor`.
- Install the bor binary at `/usr/bin/bor`.
- Dump the suitable config file (based on the network and node type provided) at `/var/lib/bor` and use it as the home dir.
- Create a systemd service named `bor` at `/lib/systemd/system/bor.service` which starts bor using the config file as `bor` user.
The releases supports both the networks i.e. Polygon Mainnet, Amoy and Mumbai (Testnet) unless explicitly specified. Before the stable release for mainnet, pre-releases will be available marked with `beta` tag for deploying on Mumbai/Amoy (testnet). On sufficient testing, stable release for mainnet will be announced with a forum post.
The releases supports both the networks i.e. Polygon Mainnet, and Amoy (Testnet) unless explicitly specified. Before the stable release for mainnet, pre-releases will be available marked with `beta` tag for deploying on Amoy (testnet). On sufficient testing, stable release for mainnet will be announced with a forum post.
### Building from source

View file

@ -61,14 +61,7 @@ func TestMain(m *testing.M) {
func runClef(t *testing.T, args ...string) *testproc {
t.Helper()
ddir, err := os.MkdirTemp("", "cleftest-*")
if err != nil {
return nil
}
t.Cleanup(func() {
os.RemoveAll(ddir)
})
ddir := t.TempDir()
return runWithKeystore(t, ddir, args...)
}

View file

@ -4,8 +4,10 @@ import (
"os"
"github.com/ethereum/go-ethereum/internal/cli"
"github.com/ethereum/go-ethereum/params"
)
func main() {
params.UpdateBorInfo()
os.Exit(cli.Run(os.Args[1:]))
}

View file

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

View file

@ -19,6 +19,7 @@ package state
import (
"errors"
"maps"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state/snapshot"
@ -145,6 +146,8 @@ type trieReader struct {
mainTrie Trie // Main trie, resolved in constructor
subRoots map[common.Address]common.Hash // Set of storage roots, cached when the account is resolved
subTries map[common.Address]Trie // Group of storage tries, cached when it's resolved
muSubRoot sync.Mutex
muSubTries sync.Mutex
}
// trieReader constructs a trie reader of the specific state. An error will be
@ -181,11 +184,14 @@ func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) {
if err != nil {
return nil, err
}
r.muSubRoot.Lock()
if account == nil {
r.subRoots[addr] = types.EmptyRootHash
} else {
r.subRoots[addr] = account.Root
}
r.muSubRoot.Unlock()
return account, nil
}
@ -221,7 +227,9 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash,
if err != nil {
return common.Hash{}, err
}
r.muSubTries.Lock()
r.subTries[addr] = tr
r.muSubTries.Unlock()
}
}
ret, err := tr.GetStorage(addr, key.Bytes())

View file

@ -332,8 +332,7 @@ func TestOpenDrops(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
@ -655,8 +654,7 @@ func TestOpenIndex(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
@ -744,8 +742,7 @@ func TestOpenHeap(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
@ -831,8 +828,8 @@ func TestOpenCap(t *testing.T) {
log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage)
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
@ -1286,8 +1283,7 @@ func TestAdd(t *testing.T) {
}
for i, tt := range tests {
// Create a temporary folder for the persistent backend
storage, _ := os.MkdirTemp("", "blobpool-")
defer os.RemoveAll(storage) // late defer, still ok
storage := t.TempDir()
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)

View file

@ -116,9 +116,8 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 {
}
func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 {
e.x.Mul(&e.x, b)
e.y.Mul(&e.y, b)
e.x.Mul(&a.x, b)
e.y.Mul(&a.y, b)
return e
}

View file

@ -135,9 +135,8 @@ func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 {
}
func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
e.x.Mul(e.x, b, pool)
e.y.Mul(e.y, b, pool)
e.x.Mul(a.x, b, pool)
e.y.Mul(a.y, b, pool)
return e
}

View file

@ -42,6 +42,7 @@ devfakeauthor = false # Run miner without validator set authorization
nodekey = "" # P2P node key file
nodekeyhex = "" # P2P node key as hex
txarrivalwait = "500ms" # Maximum duration to wait before requesting an announced transaction
txannouncementonly = false # Whether to only announce transactions to peers
[p2p.discovery]
v4disc = true # Enables the V4 discovery mechanism
v5disc = false # Enables the experimental RLPx V5 (Topic Discovery) mechanism

View file

@ -22,7 +22,7 @@ The ```bor server``` command runs the Bor client.
- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose) (default: false)
- ```chain```: Name of the chain to sync ('amoy', 'mumbai', 'mainnet') or path to a genesis file (default: mainnet)
- ```chain```: Name of the chain to sync ('amoy', 'mainnet') or path to a genesis file (default: mainnet)
- ```config```: Path to the TOML configuration file
@ -242,6 +242,8 @@ The ```bor server``` command runs the Bor client.
- ```txarrivalwait```: Maximum duration to wait for a transaction before explicitly requesting it (default: 500ms)
- ```txannouncementonly```: Whether to only announce transactions to peers (default: false)
- ```v4disc```: Enables the V4 discovery mechanism (default: true)
- ```v5disc```: Enables the experimental RLPx V5 (Topic Discovery) mechanism (default: false)

View file

@ -73,13 +73,15 @@ type Config = ethconfig.Config
// Ethereum implements the Ethereum full node service.
type Ethereum struct {
// core protocol objects
config *ethconfig.Config
txPool *txpool.TxPool
blockchain *core.BlockChain
// Handlers
txPool *txpool.TxPool
blockchain *core.BlockChain
handler *handler
discmix *enode.FairMix
ethDialCandidates enode.Iterator
snapDialCandidates enode.Iterator
// DB interfaces
chainDb ethdb.Database // Block chain database
@ -166,7 +168,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
bloomRequests: make(chan chan *bloombits.Retrieval),
bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
p2pServer: stack.Server(),
discmix: enode.NewFairMix(0),
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
closeCh: make(chan struct{}),
}
@ -306,6 +307,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
EthAPI: blockChainAPI,
checker: checker,
enableBlockTracking: eth.config.EnableBlockTracking,
txAnnouncementOnly: eth.p2pServer.TxAnnouncementOnly,
}); err != nil {
return nil, err
}
@ -320,6 +322,17 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// 1.14.8: NewOracle function definition was changed to accept (startPrice *big.Int) param.
eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, config.GPO, config.Miner.GasPrice)
// Setup DNS discovery iterators.
dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...)
if err != nil {
return nil, err
}
eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...)
if err != nil {
return nil, err
}
// Start the RPC service
eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, config.NetworkId)
@ -587,9 +600,9 @@ func (s *Ethereum) SetAuthorized(authorized bool) {
// Protocols returns all the currently configured
// network protocols to start.
func (s *Ethereum) Protocols() []p2p.Protocol {
protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.discmix)
protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates)
if s.config.SnapshotCache > 0 {
protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler))...)
protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...)
}
return protos
@ -598,7 +611,7 @@ func (s *Ethereum) Protocols() []p2p.Protocol {
// Start implements node.Lifecycle, starting all internal goroutines needed by the
// Ethereum protocol implementation.
func (s *Ethereum) Start() error {
s.setupDiscovery()
eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
// Start the bloom bits servicing goroutines
s.startBloomHandlers(params.BloomBitsBlocks)
@ -785,38 +798,6 @@ func (s *Ethereum) handleNoAckMilestoneByID(ctx context.Context, ethHandler *eth
return nil
}
func (s *Ethereum) setupDiscovery() error {
eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
// Add eth nodes from DNS.
dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
if len(s.config.EthDiscoveryURLs) > 0 {
iter, err := dnsclient.NewIterator(s.config.EthDiscoveryURLs...)
if err != nil {
return err
}
s.discmix.AddSource(iter)
}
// Add snap nodes from DNS.
if len(s.config.SnapDiscoveryURLs) > 0 {
iter, err := dnsclient.NewIterator(s.config.SnapDiscoveryURLs...)
if err != nil {
return err
}
s.discmix.AddSource(iter)
}
// Add DHT nodes from discv5.
if s.p2pServer.DiscoveryV5() != nil {
filter := eth.NewNodeFilter(s.blockchain)
iter := enode.Filter(s.p2pServer.DiscoveryV5().RandomNodes(), filter)
s.discmix.AddSource(iter)
}
return nil
}
func (s *Ethereum) getHandler() (*ethHandler, *bor.Bor, error) {
ethHandler := (*ethHandler)(s.handler)
@ -835,14 +816,13 @@ func (s *Ethereum) getHandler() (*ethHandler, *bor.Bor, error) {
// Stop implements node.Lifecycle, terminating all internal goroutines used by the
// Ethereum protocol.
func (s *Ethereum) Stop() error {
// Stop all the peer-related stuff first.
s.discmix.Close()
// Close the engine before handler else it may cause a deadlock where
// the heimdall is unresponsive and the syncing loop keeps waiting
// for a response and is unable to proceed to exit `Finalize` during
// block processing.
s.engine.Close()
s.ethDialCandidates.Close()
s.snapDialCandidates.Close()
s.handler.Stop()
// Then stop everything else.

View file

@ -99,6 +99,7 @@ type handlerConfig struct {
RequiredBlocks map[uint64]common.Hash // Hard coded map of required block hashes for sync challenges
EthAPI *ethapi.BlockChainAPI // EthAPI to interact
enableBlockTracking bool // Whether to log information collected while tracking block lifecycle
txAnnouncementOnly bool // Whether to only announce txs to peers
}
type handler struct {
@ -129,6 +130,7 @@ type handler struct {
requiredBlocks map[uint64]common.Hash
enableBlockTracking bool
txAnnouncementOnly bool
// channels for fetcher, syncer, txsyncLoop
quitSync chan struct{}
@ -159,6 +161,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
ethAPI: config.EthAPI,
requiredBlocks: config.RequiredBlocks,
enableBlockTracking: config.enableBlockTracking,
txAnnouncementOnly: config.txAnnouncementOnly,
quitSync: make(chan struct{}),
handlerDoneCh: make(chan struct{}),
handlerStartCh: make(chan struct{}),
@ -633,7 +636,7 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) {
case tx.Size() > txMaxBroadcastSize:
largeTxs++
default:
maybeDirect = true
maybeDirect = !h.txAnnouncementOnly
}
// Send the transaction (if it's small enough) directly to a subset of
// the peers that have not received it yet, ensuring that the flow of

View file

@ -454,6 +454,102 @@ func testTransactionPropagation(t *testing.T, protocol uint) {
}
}
// This test checks that transactions are only announced when txannouncementonly is enabled
func TestSendTransactionAnnouncementsOnly67(t *testing.T) {
testSendTransactionAnnouncementsOnly(t, eth.ETH67)
}
func TestSendTransactionAnnouncementsOnly68(t *testing.T) {
testSendTransactionAnnouncementsOnly(t, eth.ETH68)
}
func testSendTransactionAnnouncementsOnly(t *testing.T, protocol uint) {
t.Parallel()
// Create a source handler that has txannouncementonly enabled
source := newTestHandler()
source.handler.txAnnouncementOnly = true
defer source.close()
sink := newTestHandler()
defer sink.close()
sourcePipe, sinkPipe := p2p.MsgPipe()
defer sourcePipe.Close()
defer sinkPipe.Close()
sourcePeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, sourcePipe), sourcePipe, source.txpool)
sinkPeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, sinkPipe), sinkPipe, sink.txpool)
defer sourcePeer.Close()
defer sinkPeer.Close()
go source.handler.runEthPeer(sourcePeer, func(peer *eth.Peer) error {
return eth.Handle((*ethHandler)(source.handler), peer)
})
// Run the handshake locally
var (
genesis = source.chain.Genesis()
head = source.chain.CurrentBlock()
td = source.chain.GetTd(head.Hash(), head.Number.Uint64())
)
if err := sinkPeer.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(source.chain), forkid.NewFilter(source.chain)); err != nil {
t.Fatalf("failed to run protocol handshake: %v", err)
}
// Subscribe to all inbound network events on the sink peer
backend := new(testEthHandler)
anns := make(chan []common.Hash)
annSub := backend.txAnnounces.Subscribe(anns)
defer annSub.Unsubscribe()
bcasts := make(chan []*types.Transaction)
bcastSub := backend.txBroadcasts.Subscribe(bcasts)
defer bcastSub.Unsubscribe()
go eth.Handle(backend, sinkPeer)
// Fill the source pool with transactions and wait for them at the sink
txs := make([]*types.Transaction, 1024)
for nonce := range txs {
tx := types.NewTransaction(uint64(nonce), common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil)
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
txs[nonce] = tx
}
source.txpool.Add(txs, false, false)
// Make sure we get all the transactions as announcements
seen := make(map[common.Hash]struct{})
timeout := false
for len(seen) < len(txs) && !timeout {
switch protocol {
case 67, 68:
select {
case hashes := <-anns:
for _, hash := range hashes {
if _, ok := seen[hash]; ok {
t.Errorf("duplicate transaction announced: %x", hash)
}
seen[hash] = struct{}{}
}
case <-bcasts:
t.Errorf("received tx broadcast when txannouncementonly is true")
case <-time.After(5 * time.Second):
t.Errorf("transaction propagation timed out")
timeout = true
}
default:
panic("unsupported protocol, please extend test")
}
}
for _, tx := range txs {
if _, ok := seen[tx.Hash()]; !ok {
t.Errorf("missing transaction: %x", tx.Hash())
}
}
}
// Tests that blocks are broadcast to a sqrt number of peers only.
func TestBroadcastBlock1Peer(t *testing.T) { testBroadcastBlock(t, 1, 1) }
func TestBroadcastBlock2Peers(t *testing.T) { testBroadcastBlock(t, 2, 1) }

View file

@ -66,17 +66,3 @@ func currentENREntry(chain *core.BlockChain) *enrEntry {
ForkID: forkid.NewID(chain.Config(), chain.Genesis(), head.Number.Uint64(), head.Time),
}
}
// NewNodeFilter returns a filtering function that returns whether the provided
// enode advertises a forkid compatible with the current chain.
func NewNodeFilter(chain *core.BlockChain) func(*enode.Node) bool {
filter := forkid.NewFilter(chain)
return func(n *enode.Node) bool {
var entry enrEntry
if err := n.Load(entry); err != nil {
return false
}
err := filter(entry.ForkID)
return err == nil
}
}

View file

@ -118,6 +118,7 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2
return backend.PeerInfo(id)
},
Attributes: []enr.Entry{currentENREntry(backend.Chain())},
DialCandidates: dnsdisc,
})
}
return protocols

View file

@ -82,7 +82,13 @@ type Backend interface {
}
// MakeProtocols constructs the P2P protocol definitions for `snap`.
func MakeProtocols(backend Backend) []p2p.Protocol {
func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol {
// Filter the discovery iterator for nodes advertising snap support.
dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool {
var snap enrEntry
return n.Load(&snap) == nil
})
protocols := make([]p2p.Protocol, len(ProtocolVersions))
for i, version := range ProtocolVersions {
@ -104,6 +110,7 @@ func MakeProtocols(backend Backend) []p2p.Protocol {
return backend.PeerInfo(id)
},
Attributes: []enr.Entry{&enrEntry{}},
DialCandidates: dnsdisc,
}
}

View file

@ -89,8 +89,5 @@ var amoyTestnet = &Chain{
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
Alloc: readPrealloc("allocs/amoy.json"),
},
Bootnodes: []string{
"enode://bce861be777e91b0a5a49d58a51e14f32f201b4c6c2d1fbea6c7a1f14756cbb3f931f3188d6b65de8b07b53ff28d03b6e366d09e56360d2124a9fc5a15a0913d@54.217.171.196:30303",
"enode://4a3dc0081a346d26a73d79dd88216a9402d2292318e2db9947dbc97ea9c4afb2498dc519c0af04420dc13a238c279062da0320181e7c1461216ce4513bfd40bf@13.251.184.185:30303",
},
Bootnodes: params.AmoyBootnodes,
}

View file

@ -110,8 +110,5 @@ var mainnetBor = &Chain{
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
Alloc: readPrealloc("allocs/mainnet.json"),
},
Bootnodes: []string{
"enode://b8f1cc9c5d4403703fbf377116469667d2b1823c0daf16b7250aa576bacf399e42c3930ccfcb02c5df6879565a2b8931335565f0e8d3f8e72385ecf4a4bf160a@3.36.224.80:30303",
"enode://8729e0c825f3d9cad382555f3e46dcff21af323e89025a0e6312df541f4a9e73abfa562d64906f5e59c51fe6f0501b3e61b07979606c56329c020ed739910759@54.194.245.5:30303",
},
Bootnodes: params.BorMainnetBootnodes,
}

View file

@ -85,8 +85,5 @@ var mumbaiTestnet = &Chain{
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
Alloc: readPrealloc("allocs/mumbai.json"),
},
Bootnodes: []string{
"enode://bdcd4786a616a853b8a041f53496d853c68d99d54ff305615cd91c03cd56895e0a7f6e9f35dbf89131044e2114a9a782b792b5661e3aff07faf125a98606a071@43.200.206.40:30303",
"enode://209aaf7ed549cf4a5700fd833da25413f80a1248bd3aa7fe2a87203e3f7b236dd729579e5c8df61c97bf508281bae4969d6de76a7393bcbd04a0af70270333b3@54.216.248.9:30303",
},
Bootnodes: params.MumbaiBootnodes,
}

View file

@ -222,6 +222,9 @@ type P2PConfig struct {
// an announced transaction to arrive before explicitly requesting it
TxArrivalWait time.Duration `hcl:"-,optional" toml:"-"`
TxArrivalWaitRaw string `hcl:"txarrivalwait,optional" toml:"txarrivalwait,optional"`
// TxAnnouncementOnly is used to only announce transactions to peers
TxAnnouncementOnly bool `hcl:"txannouncementonly,optional" toml:"txannouncementonly,optional"`
}
type P2PDiscovery struct {
@ -633,6 +636,7 @@ func DefaultConfig() *Config {
NAT: "any",
NetRestrict: "",
TxArrivalWait: 500 * time.Millisecond,
TxAnnouncementOnly: false,
Discovery: &P2PDiscovery{
DiscoveryV4: true,
V5Enabled: false,
@ -1349,6 +1353,7 @@ func (c *Config) buildNode() (*node.Config, error) {
DiscoveryV4: c.P2P.Discovery.DiscoveryV4,
DiscoveryV5: c.P2P.Discovery.V5Enabled,
TxArrivalWait: c.P2P.TxArrivalWait,
TxAnnouncementOnly: c.P2P.TxAnnouncementOnly,
},
HTTPModules: c.JsonRPC.Http.API,
HTTPCors: c.JsonRPC.Http.Cors,

View file

@ -812,6 +812,13 @@ func (c *Command) Flags(config *Config) *flagset.Flagset {
Default: c.cliConfig.P2P.TxArrivalWait,
Group: "P2P",
})
f.BoolFlag(&flagset.BoolFlag{
Name: "txannouncementonly",
Usage: "Whether to only announce transactions to peers",
Value: &c.cliConfig.P2P.TxAnnouncementOnly,
Default: c.cliConfig.P2P.TxAnnouncementOnly,
Group: "P2P",
})
f.SliceStringFlag(&flagset.SliceStringFlag{
Name: "discovery.dns",
Usage: "Comma separated list of enrtree:// URLs which will be queried for nodes to connect to",

View file

@ -36,6 +36,7 @@ devfakeauthor = false
nodekey = ""
nodekeyhex = ""
txarrivalwait = "500ms"
txannouncementonly = false
[p2p.discovery]
v4disc = true
v5disc = false

View file

@ -59,10 +59,7 @@ func TestOfflineBlockPrune(t *testing.T) {
func testOfflineBlockPruneWithAmountReserved(t *testing.T, amountReserved uint64) {
t.Helper()
datadir, err := os.MkdirTemp("", "")
require.NoError(t, err, "failed to create temporary datadir")
os.RemoveAll(datadir)
datadir := t.TempDir()
chaindbPath := filepath.Join(datadir, "chaindata")
oldAncientPath := filepath.Join(chaindbPath, "ancient")

View file

@ -172,6 +172,9 @@ type Config struct {
// TxArrivalWait is the duration (ms) that the node will wait after seeing
// an announced transaction before explicitly requesting it
TxArrivalWait time.Duration
// TxAnnouncementOnly is used to only announce transactions to peers
TxAnnouncementOnly bool
}
// Server manages all peer connections.

View file

@ -35,6 +35,7 @@ gcmode = "archive"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
# [p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -34,6 +34,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -36,6 +36,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -36,6 +36,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -38,6 +38,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -36,6 +36,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -37,6 +37,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v4disc = true
# v5disc = false

View file

@ -34,6 +34,7 @@ gcmode = "archive"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -33,6 +33,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -34,6 +34,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -35,6 +35,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -36,6 +36,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -35,6 +35,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv4 = []

View file

@ -36,6 +36,7 @@ syncmode = "full"
# nodekey = ""
# nodekeyhex = ""
# txarrivalwait = "500ms"
# txannouncementonly = false
[p2p.discovery]
# v5disc = false
# bootnodesv5 = []

View file

@ -18,6 +18,8 @@ package params
import (
"fmt"
"github.com/ethereum/go-ethereum/metrics"
)
const (
@ -27,7 +29,20 @@ const (
VersionMeta = "" // Version metadata to append to the version string
)
var GitCommit string
var (
// borInfoGauge stores Bor git commit and version details.
borInfoGauge = metrics.NewRegisteredGaugeInfo("bor/info", nil)
GitCommit string
)
// UpdateBorInfo updates the bor_info metric with the current git commit and version details.
func UpdateBorInfo() {
borInfoGauge.Update(metrics.GaugeInfoValue{
"commit": GitCommit,
"version": VersionWithMeta,
})
}
// Version holds the textual version string.
var Version = func() string {

View file

@ -172,6 +172,7 @@ var nameTagMap = map[string]string{
"maxpeers": "maxpeers",
"maxpendpeers": "maxpendpeers",
"txarrivalwait": "txarrivalwait",
"txannouncementonly": "txannouncementonly",
"nat": "nat",
"nodiscover": "nodiscover",
"v5disc": "v5disc",