mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
commit
753c57e72f
40 changed files with 229 additions and 134 deletions
|
|
@ -25,6 +25,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
# maxpeers = 1
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
"muirGlacierBlock": 3395000,
|
||||
"berlinBlock": 14750000,
|
||||
"londonBlock": 23850000,
|
||||
"shanghaiBlock":50523000,
|
||||
"shanghaiBlock": 50523000,
|
||||
"cancunBlock": 54876000,
|
||||
"bor": {
|
||||
"jaipurBlock": 23850000,
|
||||
"delhiBlock": 38189056,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"berlinBlock": 13996000,
|
||||
"londonBlock": 22640000,
|
||||
"shanghaiBlock": 41874000,
|
||||
"cancunBlock": 45648608,
|
||||
"bor": {
|
||||
"jaipurBlock": 22770000,
|
||||
"delhiBlock": 29638656,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// bootnode runs a bootstrap node for the Ethereum Discovery Protocol.
|
||||
package main
|
||||
// Keep package as bootnode during upstram merge.
|
||||
package bootnode
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
|
@ -34,6 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||
)
|
||||
|
||||
// nolint
|
||||
func main() {
|
||||
var (
|
||||
listenAddr = flag.String("addr", ":30301", "listen address")
|
||||
|
|
@ -213,3 +215,12 @@ func doPortMapping(natm nat.Interface, ln *enode.LocalNode, addr *net.UDPAddr) *
|
|||
|
||||
return extaddr
|
||||
}
|
||||
|
||||
// Implemented separate functions so that there are minimal conflicts during upstream merge
|
||||
func PrintNotice(nodeKey *ecdsa.PublicKey, addr net.UDPAddr) {
|
||||
printNotice(nodeKey, addr)
|
||||
}
|
||||
|
||||
func DoPortMapping(natm nat.Interface, ln *enode.LocalNode, addr *net.UDPAddr) *net.UDPAddr {
|
||||
return doPortMapping(natm, ln, addr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -73,6 +74,7 @@ type stateObject struct {
|
|||
trie Trie // storage trie, which becomes non-nil on first access
|
||||
code Code // contract bytecode, which gets set when code is loaded
|
||||
|
||||
storageMutex sync.Mutex
|
||||
originStorage Storage // Storage cache of original entries to dedup rewrites
|
||||
pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block
|
||||
dirtyStorage Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction
|
||||
|
|
@ -175,6 +177,8 @@ func (s *stateObject) GetState(key common.Hash) common.Hash {
|
|||
|
||||
// GetCommittedState retrieves a value from the committed account storage trie.
|
||||
func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||
s.storageMutex.Lock()
|
||||
defer s.storageMutex.Unlock()
|
||||
// If we have a pending write or clean cached, return that
|
||||
if value, pending := s.pendingStorage[key]; pending {
|
||||
return value
|
||||
|
|
@ -183,6 +187,7 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
|||
if value, cached := s.originStorage[key]; cached {
|
||||
return value
|
||||
}
|
||||
|
||||
// If the object was destructed in *this* block (and potentially resurrected),
|
||||
// the storage has been cleared out, and we should *not* consult the previous
|
||||
// database about any storage values. The only possible alternatives are:
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ type Block struct {
|
|||
// inter-peer block relay.
|
||||
ReceivedAt time.Time
|
||||
ReceivedFrom interface{}
|
||||
AnnouncedAt *time.Time
|
||||
}
|
||||
|
||||
// "external" block encoding. used for eth protocol, etc.
|
||||
|
|
|
|||
|
|
@ -373,20 +373,20 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
|||
itx.BlobHashes = dec.BlobVersionedHashes
|
||||
|
||||
// signature R
|
||||
var ok bool
|
||||
var overflow bool
|
||||
if dec.R == nil {
|
||||
return errors.New("missing required field 'r' in transaction")
|
||||
}
|
||||
itx.R, ok = uint256.FromBig((*big.Int)(dec.R))
|
||||
if !ok {
|
||||
itx.R, overflow = uint256.FromBig((*big.Int)(dec.R))
|
||||
if overflow {
|
||||
return errors.New("'r' value overflows uint256")
|
||||
}
|
||||
// signature S
|
||||
if dec.S == nil {
|
||||
return errors.New("missing required field 's' in transaction")
|
||||
}
|
||||
itx.S, ok = uint256.FromBig((*big.Int)(dec.S))
|
||||
if !ok {
|
||||
itx.S, overflow = uint256.FromBig((*big.Int)(dec.S))
|
||||
if overflow {
|
||||
return errors.New("'s' value overflows uint256")
|
||||
}
|
||||
// signature V
|
||||
|
|
@ -394,8 +394,8 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
itx.V, ok = uint256.FromBig(vbig)
|
||||
if !ok {
|
||||
itx.V, overflow = uint256.FromBig(vbig)
|
||||
if overflow {
|
||||
return errors.New("'v' value overflows uint256")
|
||||
}
|
||||
if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ devfakeauthor = false # Run miner without validator set authorization
|
|||
"32000000" = "0x875500011e5eecc0c554f95d07b31cf59df4ca2505f4dbbfffa7d4e4da917c68"
|
||||
|
||||
[log]
|
||||
vmodule = "" # Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)
|
||||
json = false # Format logs with JSON
|
||||
backtrace = "" # Request a stack trace at a specific logging statement (e.g. "block.go:271")
|
||||
debug = true # Prepends log messages with call-site location (file and line number) - {requires some effort}
|
||||
vmodule = "" # Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)
|
||||
json = false # Format logs with JSON
|
||||
backtrace = "" # Request a stack trace at a specific logging statement (e.g. "block.go:271")
|
||||
debug = true # Prepends log messages with call-site location (file and line number)
|
||||
enable-block-tracking = false # Enables additional logging of information collected while tracking block lifecycle
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50 # Maximum number of network peers (network disabled if set to 0)
|
||||
|
|
|
|||
|
|
@ -204,6 +204,8 @@ The ```bor server``` command runs the Bor client.
|
|||
|
||||
- ```log.debug```: Prepends log messages with call-site location (file and line number) (default: false)
|
||||
|
||||
- ```log.enable-block-tracking```: Enables additional logging of information collected while tracking block lifecycle (default: false)
|
||||
|
||||
- ```log.json```: Format logs with JSON (default: false)
|
||||
|
||||
- ```vmodule```: Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)
|
||||
|
|
|
|||
|
|
@ -272,18 +272,19 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
|||
// Permit the downloader to use the trie cache allowance during fast sync
|
||||
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
|
||||
if eth.handler, err = newHandler(&handlerConfig{
|
||||
Database: chainDb,
|
||||
Chain: eth.blockchain,
|
||||
TxPool: eth.txPool,
|
||||
Merger: eth.merger,
|
||||
Network: config.NetworkId,
|
||||
Sync: config.SyncMode,
|
||||
BloomCache: uint64(cacheLimit),
|
||||
EventMux: eth.eventMux,
|
||||
RequiredBlocks: config.RequiredBlocks,
|
||||
EthAPI: blockChainAPI,
|
||||
checker: checker,
|
||||
txArrivalWait: eth.p2pServer.TxArrivalWait,
|
||||
Database: chainDb,
|
||||
Chain: eth.blockchain,
|
||||
TxPool: eth.txPool,
|
||||
Merger: eth.merger,
|
||||
Network: config.NetworkId,
|
||||
Sync: config.SyncMode,
|
||||
BloomCache: uint64(cacheLimit),
|
||||
EventMux: eth.eventMux,
|
||||
RequiredBlocks: config.RequiredBlocks,
|
||||
EthAPI: blockChainAPI,
|
||||
checker: checker,
|
||||
txArrivalWait: eth.p2pServer.TxArrivalWait,
|
||||
enableBlockTracking: eth.config.EnableBlockTracking,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ var (
|
|||
rewindLengthMeter = metrics.NewRegisteredMeter("chain/autorewind/length", nil)
|
||||
)
|
||||
|
||||
const maxRewindLen uint64 = 126
|
||||
|
||||
type borVerifier struct {
|
||||
verify func(ctx context.Context, eth *Ethereum, handler *ethHandler, start uint64, end uint64, hash string, isCheckpoint bool) (string, error)
|
||||
}
|
||||
|
|
@ -117,8 +119,8 @@ func borVerify(ctx context.Context, eth *Ethereum, handler *ethHandler, start ui
|
|||
}
|
||||
}
|
||||
|
||||
if head-rewindTo > 255 {
|
||||
rewindTo = head - 255
|
||||
if head-rewindTo > maxRewindLen {
|
||||
rewindTo = head - maxRewindLen
|
||||
}
|
||||
|
||||
if isCheckpoint {
|
||||
|
|
|
|||
|
|
@ -204,6 +204,9 @@ type Config struct {
|
|||
|
||||
// OverrideVerkle (TODO: remove after the fork)
|
||||
OverrideVerkle *big.Int `toml:",omitempty"`
|
||||
|
||||
// EnableBlockTracking allows logging of information collected while tracking block lifecycle
|
||||
EnableBlockTracking bool
|
||||
}
|
||||
|
||||
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
||||
|
|
|
|||
|
|
@ -114,18 +114,20 @@ type blockAnnounce struct {
|
|||
|
||||
// headerFilterTask represents a batch of headers needing fetcher filtering.
|
||||
type headerFilterTask struct {
|
||||
peer string // The source peer of block headers
|
||||
headers []*types.Header // Collection of headers to filter
|
||||
time time.Time // Arrival time of the headers
|
||||
peer string // The source peer of block headers
|
||||
headers []*types.Header // Collection of headers to filter
|
||||
time time.Time // Arrival time of the headers
|
||||
announcedTime time.Time // Announcement time of the availability of the block
|
||||
}
|
||||
|
||||
// bodyFilterTask represents a batch of block bodies (transactions and uncles)
|
||||
// needing fetcher filtering.
|
||||
type bodyFilterTask struct {
|
||||
peer string // The source peer of block bodies
|
||||
transactions [][]*types.Transaction // Collection of transactions per block bodies
|
||||
uncles [][]*types.Header // Collection of uncles per block bodies
|
||||
time time.Time // Arrival time of the blocks' contents
|
||||
peer string // The source peer of block bodies
|
||||
transactions [][]*types.Transaction // Collection of transactions per block bodies
|
||||
uncles [][]*types.Header // Collection of uncles per block bodies
|
||||
time time.Time // Arrival time of the blocks' contents
|
||||
announcedTime time.Time // Announcement time of the availability of the block
|
||||
}
|
||||
|
||||
// blockOrHeaderInject represents a schedules import operation.
|
||||
|
|
@ -197,34 +199,38 @@ type BlockFetcher struct {
|
|||
fetchingHook func([]common.Hash) // Method to call upon starting a block (eth/61) or header (eth/62) fetch
|
||||
completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
|
||||
importedHook func(*types.Header, *types.Block) // Method to call upon successful header or block import (both eth/61 and eth/62)
|
||||
|
||||
// Logging
|
||||
enableBlockTracking bool // Whether to log information collected while tracking block lifecycle
|
||||
}
|
||||
|
||||
// NewBlockFetcher creates a block fetcher to retrieve blocks based on hash announcements.
|
||||
func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn) *BlockFetcher {
|
||||
func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn, enableBlockTracking bool) *BlockFetcher {
|
||||
return &BlockFetcher{
|
||||
light: light,
|
||||
notify: make(chan *blockAnnounce),
|
||||
inject: make(chan *blockOrHeaderInject),
|
||||
headerFilter: make(chan chan *headerFilterTask),
|
||||
bodyFilter: make(chan chan *bodyFilterTask),
|
||||
done: make(chan common.Hash),
|
||||
quit: make(chan struct{}),
|
||||
announces: make(map[string]int),
|
||||
announced: make(map[common.Hash][]*blockAnnounce),
|
||||
fetching: make(map[common.Hash]*blockAnnounce),
|
||||
fetched: make(map[common.Hash][]*blockAnnounce),
|
||||
completing: make(map[common.Hash]*blockAnnounce),
|
||||
queue: prque.New[int64, *blockOrHeaderInject](nil),
|
||||
queues: make(map[string]int),
|
||||
queued: make(map[common.Hash]*blockOrHeaderInject),
|
||||
getHeader: getHeader,
|
||||
getBlock: getBlock,
|
||||
verifyHeader: verifyHeader,
|
||||
broadcastBlock: broadcastBlock,
|
||||
chainHeight: chainHeight,
|
||||
insertHeaders: insertHeaders,
|
||||
insertChain: insertChain,
|
||||
dropPeer: dropPeer,
|
||||
light: light,
|
||||
notify: make(chan *blockAnnounce),
|
||||
inject: make(chan *blockOrHeaderInject),
|
||||
headerFilter: make(chan chan *headerFilterTask),
|
||||
bodyFilter: make(chan chan *bodyFilterTask),
|
||||
done: make(chan common.Hash),
|
||||
quit: make(chan struct{}),
|
||||
announces: make(map[string]int),
|
||||
announced: make(map[common.Hash][]*blockAnnounce),
|
||||
fetching: make(map[common.Hash]*blockAnnounce),
|
||||
fetched: make(map[common.Hash][]*blockAnnounce),
|
||||
completing: make(map[common.Hash]*blockAnnounce),
|
||||
queue: prque.New[int64, *blockOrHeaderInject](nil),
|
||||
queues: make(map[string]int),
|
||||
queued: make(map[common.Hash]*blockOrHeaderInject),
|
||||
getHeader: getHeader,
|
||||
getBlock: getBlock,
|
||||
verifyHeader: verifyHeader,
|
||||
broadcastBlock: broadcastBlock,
|
||||
chainHeight: chainHeight,
|
||||
insertHeaders: insertHeaders,
|
||||
insertChain: insertChain,
|
||||
dropPeer: dropPeer,
|
||||
enableBlockTracking: enableBlockTracking,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +282,7 @@ func (f *BlockFetcher) Enqueue(peer string, block *types.Block) error {
|
|||
|
||||
// FilterHeaders extracts all the headers that were explicitly requested by the fetcher,
|
||||
// returning those that should be handled differently.
|
||||
func (f *BlockFetcher) FilterHeaders(peer string, headers []*types.Header, time time.Time) []*types.Header {
|
||||
func (f *BlockFetcher) FilterHeaders(peer string, headers []*types.Header, time time.Time, announcedAt time.Time) []*types.Header {
|
||||
log.Trace("Filtering headers", "peer", peer, "headers", len(headers))
|
||||
|
||||
// Send the filter channel to the fetcher
|
||||
|
|
@ -289,7 +295,7 @@ func (f *BlockFetcher) FilterHeaders(peer string, headers []*types.Header, time
|
|||
}
|
||||
// Request the filtering of the header list
|
||||
select {
|
||||
case filter <- &headerFilterTask{peer: peer, headers: headers, time: time}:
|
||||
case filter <- &headerFilterTask{peer: peer, headers: headers, time: time, announcedTime: announcedAt}:
|
||||
case <-f.quit:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -304,7 +310,7 @@ func (f *BlockFetcher) FilterHeaders(peer string, headers []*types.Header, time
|
|||
|
||||
// FilterBodies extracts all the block bodies that were explicitly requested by
|
||||
// the fetcher, returning those that should be handled differently.
|
||||
func (f *BlockFetcher) FilterBodies(peer string, transactions [][]*types.Transaction, uncles [][]*types.Header, time time.Time) ([][]*types.Transaction, [][]*types.Header) {
|
||||
func (f *BlockFetcher) FilterBodies(peer string, transactions [][]*types.Transaction, uncles [][]*types.Header, time time.Time, announcedAt time.Time) ([][]*types.Transaction, [][]*types.Header) {
|
||||
log.Trace("Filtering bodies", "peer", peer, "txs", len(transactions), "uncles", len(uncles))
|
||||
|
||||
// Send the filter channel to the fetcher
|
||||
|
|
@ -317,7 +323,7 @@ func (f *BlockFetcher) FilterBodies(peer string, transactions [][]*types.Transac
|
|||
}
|
||||
// Request the filtering of the body list
|
||||
select {
|
||||
case filter <- &bodyFilterTask{peer: peer, transactions: transactions, uncles: uncles, time: time}:
|
||||
case filter <- &bodyFilterTask{peer: peer, transactions: transactions, uncles: uncles, time: time, announcedTime: announcedAt}:
|
||||
case <-f.quit:
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -480,7 +486,7 @@ func (f *BlockFetcher) loop() {
|
|||
log.Trace("Fetching scheduled headers", "peer", peer, "list", hashes)
|
||||
|
||||
// Create a closure of the fetch and schedule in on a new thread
|
||||
fetchHeader, hashes := f.fetching[hashes[0]].fetchHeader, hashes
|
||||
fetchHeader, hashes, announcedAt := f.fetching[hashes[0]].fetchHeader, hashes, f.fetching[hashes[0]].time
|
||||
go func(peer string) {
|
||||
if f.fetchingHook != nil {
|
||||
f.fetchingHook(hashes)
|
||||
|
|
@ -504,7 +510,7 @@ func (f *BlockFetcher) loop() {
|
|||
select {
|
||||
case res := <-resCh:
|
||||
res.Done <- nil
|
||||
f.FilterHeaders(peer, *res.Res.(*eth.BlockHeadersPacket), time.Now().Add(res.Time))
|
||||
f.FilterHeaders(peer, *res.Res.(*eth.BlockHeadersPacket), time.Now(), announcedAt)
|
||||
|
||||
case <-timeout.C:
|
||||
// The peer didn't respond in time. The request
|
||||
|
|
@ -547,6 +553,7 @@ func (f *BlockFetcher) loop() {
|
|||
|
||||
fetchBodies := f.completing[hashes[0]].fetchBodies
|
||||
bodyFetchMeter.Mark(int64(len(hashes)))
|
||||
announcedAt := f.completing[hashes[0]].time
|
||||
|
||||
go func(peer string, hashes []common.Hash) {
|
||||
resCh := make(chan *eth.Response)
|
||||
|
|
@ -565,7 +572,7 @@ func (f *BlockFetcher) loop() {
|
|||
res.Done <- nil
|
||||
// Ignoring withdrawals here, since the block fetcher is not used post-merge.
|
||||
txs, uncles, _ := res.Res.(*eth.BlockBodiesPacket).Unpack()
|
||||
f.FilterBodies(peer, txs, uncles, time.Now())
|
||||
f.FilterBodies(peer, txs, uncles, time.Now(), announcedAt)
|
||||
|
||||
case <-timeout.C:
|
||||
// The peer didn't respond in time. The request
|
||||
|
|
@ -631,6 +638,7 @@ func (f *BlockFetcher) loop() {
|
|||
|
||||
block := types.NewBlockWithHeader(header)
|
||||
block.ReceivedAt = task.time
|
||||
block.AnnouncedAt = &task.announcedTime
|
||||
|
||||
complete = append(complete, block)
|
||||
f.completing[hash] = announce
|
||||
|
|
@ -725,6 +733,7 @@ func (f *BlockFetcher) loop() {
|
|||
if f.getBlock(hash) == nil {
|
||||
block := types.NewBlockWithHeader(announce.header).WithBody(task.transactions[i], task.uncles[i])
|
||||
block.ReceivedAt = task.time
|
||||
block.AnnouncedAt = &task.announcedTime
|
||||
blocks = append(blocks, block)
|
||||
} else {
|
||||
f.forgetHash(hash)
|
||||
|
|
@ -923,6 +932,31 @@ func (f *BlockFetcher) importBlocks(peer string, block *types.Block) {
|
|||
log.Debug("Propagated block import failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
if f.enableBlockTracking {
|
||||
// Log the insertion event
|
||||
var (
|
||||
msg string
|
||||
delayInMs uint64
|
||||
prettyDelay common.PrettyDuration
|
||||
)
|
||||
|
||||
if block.AnnouncedAt != nil {
|
||||
msg = "[block tracker] Inserted new block with announcement"
|
||||
delayInMs = uint64(time.Since(*block.AnnouncedAt).Milliseconds())
|
||||
prettyDelay = common.PrettyDuration(time.Since(*block.AnnouncedAt))
|
||||
} else {
|
||||
msg = "[block tracker] Inserted new block without announcement"
|
||||
delayInMs = uint64(time.Since(block.ReceivedAt).Milliseconds())
|
||||
prettyDelay = common.PrettyDuration(time.Since(block.ReceivedAt))
|
||||
}
|
||||
|
||||
totalDelayInMs := uint64(time.Now().UnixMilli()) - block.Time()*1000
|
||||
totalDelay := common.PrettyDuration(time.Millisecond * time.Duration(totalDelayInMs))
|
||||
|
||||
log.Info(msg, "number", block.Number().Uint64(), "hash", hash, "delay", prettyDelay, "delayInMs", delayInMs, "totalDelay", totalDelay, "totalDelayInMs", totalDelayInMs)
|
||||
}
|
||||
|
||||
// If import succeeded, broadcast the block
|
||||
blockAnnounceOutTimer.UpdateSince(block.ReceivedAt)
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ func newTester(light bool) *fetcherTester {
|
|||
blocks: map[common.Hash]*types.Block{genesis.Hash(): genesis},
|
||||
drops: make(map[string]bool),
|
||||
}
|
||||
tester.fetcher = NewBlockFetcher(light, tester.getHeader, tester.getBlock, tester.verifyHeader, tester.broadcastBlock, tester.chainHeight, tester.insertHeaders, tester.insertChain, tester.dropPeer)
|
||||
tester.fetcher = NewBlockFetcher(light, tester.getHeader, tester.getBlock, tester.verifyHeader, tester.broadcastBlock, tester.chainHeight, tester.insertHeaders, tester.insertChain, tester.dropPeer, false)
|
||||
tester.fetcher.Start()
|
||||
|
||||
return tester
|
||||
|
|
|
|||
|
|
@ -85,18 +85,19 @@ type txPool interface {
|
|||
// handlerConfig is the collection of initialization parameters to create a full
|
||||
// node network handler.
|
||||
type handlerConfig struct {
|
||||
Database ethdb.Database // Database for direct sync insertions
|
||||
Chain *core.BlockChain // Blockchain to serve data from
|
||||
TxPool txPool // Transaction pool to propagate from
|
||||
Merger *consensus.Merger // The manager for eth1/2 transition
|
||||
Network uint64 // Network identifier to adfvertise
|
||||
Sync downloader.SyncMode // Whether to snap or full sync
|
||||
BloomCache uint64 // Megabytes to alloc for snap sync bloom
|
||||
EventMux *event.TypeMux // Legacy event mux, deprecate for `feed`
|
||||
txArrivalWait time.Duration // Maximum duration to wait for an announced tx before requesting it
|
||||
checker ethereum.ChainValidator
|
||||
RequiredBlocks map[uint64]common.Hash // Hard coded map of required block hashes for sync challenges
|
||||
EthAPI *ethapi.BlockChainAPI // EthAPI to interact
|
||||
Database ethdb.Database // Database for direct sync insertions
|
||||
Chain *core.BlockChain // Blockchain to serve data from
|
||||
TxPool txPool // Transaction pool to propagate from
|
||||
Merger *consensus.Merger // The manager for eth1/2 transition
|
||||
Network uint64 // Network identifier to adfvertise
|
||||
Sync downloader.SyncMode // Whether to snap or full sync
|
||||
BloomCache uint64 // Megabytes to alloc for snap sync bloom
|
||||
EventMux *event.TypeMux // Legacy event mux, deprecate for `feed`
|
||||
txArrivalWait time.Duration // Maximum duration to wait for an announced tx before requesting it
|
||||
checker ethereum.ChainValidator
|
||||
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
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
|
|
@ -126,6 +127,8 @@ type handler struct {
|
|||
|
||||
requiredBlocks map[uint64]common.Hash
|
||||
|
||||
enableBlockTracking bool
|
||||
|
||||
// channels for fetcher, syncer, txsyncLoop
|
||||
quitSync chan struct{}
|
||||
|
||||
|
|
@ -144,19 +147,20 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
|||
}
|
||||
|
||||
h := &handler{
|
||||
networkID: config.Network,
|
||||
forkFilter: forkid.NewFilter(config.Chain),
|
||||
eventMux: config.EventMux,
|
||||
database: config.Database,
|
||||
txpool: config.TxPool,
|
||||
chain: config.Chain,
|
||||
peers: newPeerSet(),
|
||||
merger: config.Merger,
|
||||
ethAPI: config.EthAPI,
|
||||
requiredBlocks: config.RequiredBlocks,
|
||||
quitSync: make(chan struct{}),
|
||||
handlerDoneCh: make(chan struct{}),
|
||||
handlerStartCh: make(chan struct{}),
|
||||
networkID: config.Network,
|
||||
forkFilter: forkid.NewFilter(config.Chain),
|
||||
eventMux: config.EventMux,
|
||||
database: config.Database,
|
||||
txpool: config.TxPool,
|
||||
chain: config.Chain,
|
||||
peers: newPeerSet(),
|
||||
merger: config.Merger,
|
||||
ethAPI: config.EthAPI,
|
||||
requiredBlocks: config.RequiredBlocks,
|
||||
enableBlockTracking: config.enableBlockTracking,
|
||||
quitSync: make(chan struct{}),
|
||||
handlerDoneCh: make(chan struct{}),
|
||||
handlerStartCh: make(chan struct{}),
|
||||
}
|
||||
if config.Sync == downloader.FullSync {
|
||||
// The database seems empty as the current block is the genesis. Yet the snap
|
||||
|
|
@ -295,7 +299,7 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
|||
|
||||
return n, err
|
||||
}
|
||||
h.blockFetcher = fetcher.NewBlockFetcher(false, nil, h.chain.GetBlockByHash, validator, h.BroadcastBlock, heighter, nil, inserter, h.removePeer)
|
||||
h.blockFetcher = fetcher.NewBlockFetcher(false, nil, h.chain.GetBlockByHash, validator, h.BroadcastBlock, heighter, nil, inserter, h.removePeer, h.enableBlockTracking)
|
||||
|
||||
fetchTx := func(peer string, hashes []common.Hash) error {
|
||||
p := h.peers.peer(peer)
|
||||
|
|
@ -688,6 +692,11 @@ func (h *handler) minedBroadcastLoop() {
|
|||
|
||||
for obj := range h.minedBlockSub.Chan() {
|
||||
if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
||||
if h.enableBlockTracking {
|
||||
delayInMs := uint64(time.Now().UnixMilli()) - ev.Block.Time()*1000
|
||||
delay := common.PrettyDuration(time.Millisecond * time.Duration(delayInMs))
|
||||
log.Info("[block tracker] Broadcasting mined block", "number", ev.Block.NumberU64(), "hash", ev.Block.Hash(), "blockTime", ev.Block.Time(), "now", time.Now().Unix(), "delay", delay, "delayInMs", delayInMs)
|
||||
}
|
||||
h.BroadcastBlock(ev.Block, true) // First propagate block to peers
|
||||
h.BroadcastBlock(ev.Block, false) // Only then announce to the rest
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,8 +382,10 @@ func handleNewBlock(backend Backend, msg Decoder, peer *Peer) error {
|
|||
return nil // TODO(karalabe): return error eventually, but wait a few releases
|
||||
}
|
||||
|
||||
msgTime := msg.Time()
|
||||
ann.Block.ReceivedAt = msg.Time()
|
||||
ann.Block.ReceivedFrom = peer
|
||||
ann.Block.AnnouncedAt = &msgTime
|
||||
|
||||
// Mark the peer as owning the block
|
||||
peer.markBlock(ann.Block.Hash())
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/bootnode"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/cli/flagset"
|
||||
|
|
@ -213,33 +214,25 @@ func (b *BootnodeCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
conn, err := net.ListenUDP("udp", addr)
|
||||
|
||||
if err != nil {
|
||||
b.UI.Error(fmt.Sprintf("failed to listen udp addr '%s': %v", b.listenAddr, err))
|
||||
return 1
|
||||
}
|
||||
|
||||
realaddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
if natm != nil {
|
||||
if !realaddr.IP.IsLoopback() {
|
||||
go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
|
||||
}
|
||||
|
||||
if ext, err := natm.ExternalIP(); err == nil {
|
||||
// nolint: govet
|
||||
realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
|
||||
}
|
||||
}
|
||||
|
||||
n := enode.NewV4(&nodeKey.PublicKey, addr.IP, addr.Port, addr.Port)
|
||||
b.UI.Info(n.String())
|
||||
|
||||
if b.dryRun {
|
||||
return 0
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
db, _ := enode.OpenDB("")
|
||||
ln := enode.NewLocalNode(db, nodeKey)
|
||||
|
||||
listenerAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
if natm != nil {
|
||||
natAddr := bootnode.DoPortMapping(natm, ln, listenerAddr)
|
||||
if natAddr != nil {
|
||||
listenerAddr = natAddr
|
||||
}
|
||||
}
|
||||
|
||||
bootnode.PrintNotice(&nodeKey.PublicKey, *listenerAddr)
|
||||
|
||||
cfg := discover.Config{
|
||||
PrivateKey: nodeKey,
|
||||
Log: log.Root(),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ var mainnetBor = &Chain{
|
|||
BerlinBlock: big.NewInt(14750000),
|
||||
LondonBlock: big.NewInt(23850000),
|
||||
ShanghaiBlock: big.NewInt(50523000),
|
||||
CancunBlock: big.NewInt(54876000),
|
||||
Bor: ¶ms.BorConfig{
|
||||
JaipurBlock: big.NewInt(23850000),
|
||||
DelhiBlock: big.NewInt(38189056),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ var mumbaiTestnet = &Chain{
|
|||
BerlinBlock: big.NewInt(13996000),
|
||||
LondonBlock: big.NewInt(22640000),
|
||||
ShanghaiBlock: big.NewInt(41874000),
|
||||
CancunBlock: big.NewInt(45648608),
|
||||
Bor: ¶ms.BorConfig{
|
||||
JaipurBlock: big.NewInt(22770000),
|
||||
DelhiBlock: big.NewInt(29638656),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"berlinBlock": 13996000,
|
||||
"londonBlock": 13996000,
|
||||
"shanghaiBlock": 41874000,
|
||||
"cancunBlock": 45648608,
|
||||
"bor": {
|
||||
"period": {
|
||||
"0": 2,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"berlinBlock":13996000,
|
||||
"londonBlock":13996000,
|
||||
"shanghaiBlock": 41874000,
|
||||
"cancunBlock": 45648608,
|
||||
"bor":{
|
||||
"period":{
|
||||
"0":2,
|
||||
|
|
|
|||
|
|
@ -154,6 +154,9 @@ type LoggingConfig struct {
|
|||
// Prepends log messages with call-site location (file and line number)
|
||||
Debug bool `hcl:"debug,optional" toml:"debug,optional"`
|
||||
|
||||
// EnableBlockTracking allows logging of information collected while tracking block lifecycle
|
||||
EnableBlockTracking bool `hcl:"enable-block-tracking,optional" toml:"enable-block-tracking,optional"`
|
||||
|
||||
// TODO - implement this
|
||||
// // Write execution trace to the given file
|
||||
// Trace string `hcl:"trace,optional" toml:"trace,optional"`
|
||||
|
|
@ -606,10 +609,11 @@ func DefaultConfig() *Config {
|
|||
DBEngine: "leveldb",
|
||||
KeyStoreDir: "",
|
||||
Logging: &LoggingConfig{
|
||||
Vmodule: "",
|
||||
Json: false,
|
||||
Backtrace: "",
|
||||
Debug: false,
|
||||
Vmodule: "",
|
||||
Json: false,
|
||||
Backtrace: "",
|
||||
Debug: false,
|
||||
EnableBlockTracking: false,
|
||||
},
|
||||
RPCBatchLimit: 100,
|
||||
RPCReturnDataLimit: 100000,
|
||||
|
|
@ -1186,6 +1190,8 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
|
|||
n.DatabaseFreezer = c.Ancient
|
||||
}
|
||||
|
||||
n.EnableBlockTracking = c.Logging.EnableBlockTracking
|
||||
|
||||
return &n, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,13 @@ func (c *Command) Flags(config *Config) *flagset.Flagset {
|
|||
Default: c.cliConfig.Logging.Debug,
|
||||
Group: "Logging",
|
||||
})
|
||||
f.BoolFlag(&flagset.BoolFlag{
|
||||
Name: "log.enable-block-tracking",
|
||||
Usage: "Enables additional logging of information collected while tracking block lifecycle",
|
||||
Value: &c.cliConfig.Logging.EnableBlockTracking,
|
||||
Default: c.cliConfig.Logging.EnableBlockTracking,
|
||||
Group: "Logging",
|
||||
})
|
||||
|
||||
// heimdall
|
||||
f.StringFlag(&flagset.StringFlag{
|
||||
|
|
|
|||
|
|
@ -920,7 +920,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||
EnableMVHashMap := w.chainConfig.IsCancun(env.header.Number)
|
||||
|
||||
// create and add empty mvHashMap in statedb
|
||||
if EnableMVHashMap {
|
||||
if EnableMVHashMap && w.IsRunning() {
|
||||
deps = map[int]map[int]bool{}
|
||||
|
||||
chDeps = make(chan blockstm.TxDep)
|
||||
|
|
@ -955,8 +955,16 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||
|
||||
mainloop:
|
||||
for {
|
||||
// Check interruption signal and abort building if it's fired.
|
||||
if interrupt != nil {
|
||||
if signal := interrupt.Load(); signal != commitInterruptNone {
|
||||
breakCause = "interrupt"
|
||||
return signalToErr(signal)
|
||||
}
|
||||
}
|
||||
|
||||
if interruptCtx != nil {
|
||||
if EnableMVHashMap {
|
||||
if EnableMVHashMap && w.IsRunning() {
|
||||
env.state.AddEmptyMVHashMap()
|
||||
}
|
||||
|
||||
|
|
@ -970,13 +978,6 @@ mainloop:
|
|||
}
|
||||
}
|
||||
|
||||
// Check interruption signal and abort building if it's fired.
|
||||
if interrupt != nil {
|
||||
if signal := interrupt.Load(); signal != commitInterruptNone {
|
||||
breakCause = "interrupt"
|
||||
return signalToErr(signal)
|
||||
}
|
||||
}
|
||||
// If we don't have enough gas for any further transactions then we're done.
|
||||
if env.gasPool.Gas() < params.TxGas {
|
||||
breakCause = "Not enough gas for further transactions"
|
||||
|
|
@ -1055,7 +1056,7 @@ mainloop:
|
|||
coalescedLogs = append(coalescedLogs, logs...)
|
||||
env.tcount++
|
||||
|
||||
if EnableMVHashMap {
|
||||
if EnableMVHashMap && w.IsRunning() {
|
||||
env.depsMVFullWriteList = append(env.depsMVFullWriteList, env.state.MVFullWriteList())
|
||||
env.mvReadMapList = append(env.mvReadMapList, env.state.MVReadMap())
|
||||
|
||||
|
|
@ -1085,7 +1086,7 @@ mainloop:
|
|||
txs.Pop()
|
||||
}
|
||||
|
||||
if EnableMVHashMap {
|
||||
if EnableMVHashMap && w.IsRunning() {
|
||||
env.state.ClearReadMap()
|
||||
env.state.ClearWriteMap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ gcmode = "archive"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 20
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source: bor-profile
|
||||
Version: 1.2.3
|
||||
Version: 1.2.7
|
||||
Section: develop
|
||||
Priority: standard
|
||||
Maintainer: Polygon <release-team@polygon.technology>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ gcmode = "archive"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 1
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ syncmode = "full"
|
|||
# json = false
|
||||
# backtrace = ""
|
||||
# debug = true
|
||||
# enable-block-tracking = false
|
||||
|
||||
[p2p]
|
||||
maxpeers = 50
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ var (
|
|||
BerlinBlock: big.NewInt(13996000),
|
||||
LondonBlock: big.NewInt(22640000),
|
||||
ShanghaiBlock: big.NewInt(41874000),
|
||||
CancunBlock: big.NewInt(45648608),
|
||||
Bor: &BorConfig{
|
||||
JaipurBlock: big.NewInt(22770000),
|
||||
DelhiBlock: big.NewInt(29638656),
|
||||
|
|
@ -261,6 +262,7 @@ var (
|
|||
BerlinBlock: big.NewInt(14750000),
|
||||
LondonBlock: big.NewInt(23850000),
|
||||
ShanghaiBlock: big.NewInt(50523000),
|
||||
CancunBlock: big.NewInt(54876000),
|
||||
Bor: &BorConfig{
|
||||
JaipurBlock: big.NewInt(23850000),
|
||||
DelhiBlock: big.NewInt(38189056),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 2 // Minor version component of the current release
|
||||
VersionPatch = 3 // Patch version component of the current release
|
||||
VersionPatch = 7 // Patch version component of the current release
|
||||
VersionMeta = "" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue