Merge branch 'develop' into merge_develop_to_big_merge_v1.10.16_v1.12.2
This commit is contained in:
commit
b5e862b9a8
29
README.md
29
README.md
@ -247,6 +247,35 @@ APIs!**
|
||||
- [BSC-Deploy](https://github.com/bnb-chain/node-deploy/): deploy tool for setting up both BNB Beacon Chain, BNB Smart Chain and the cross chain infrastructure between them.
|
||||
- [BSC-Docker](https://github.com/bnb-chain/bsc-docker): deploy tool for setting up local BSC cluster in container.
|
||||
|
||||
|
||||
## Running a bootnode
|
||||
|
||||
Bootnodes are super-lightweight nodes that are not behind a NAT and are running just discovery protocol. When you start up a node it should log your enode, which is a public identifier that others can use to connect to your node.
|
||||
|
||||
First the bootnode requires a key, which can be created with the following command, which will save a key to boot.key:
|
||||
|
||||
```
|
||||
bootnode -genkey boot.key
|
||||
```
|
||||
|
||||
This key can then be used to generate a bootnode as follows:
|
||||
|
||||
```
|
||||
bootnode -nodekey boot.key -addr :30311 -network bsc
|
||||
```
|
||||
|
||||
The choice of port passed to -addr is arbitrary.
|
||||
The bootnode command returns the following logs to the terminal, confirming that it is running:
|
||||
|
||||
```
|
||||
enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@127.0.0.1:0?discport=30311
|
||||
Note: you're using cmd/bootnode, a developer tool.
|
||||
We recommend using a regular node as bootstrap node for production deployments.
|
||||
INFO [08-21|11:11:30.687] New local node record seq=1,692,616,290,684 id=2c9af1742f8f85ce ip=<nil> udp=0 tcp=0
|
||||
INFO [08-21|12:11:30.753] New local node record seq=1,692,616,290,685 id=2c9af1742f8f85ce ip=54.217.128.118 udp=30311 tcp=0
|
||||
INFO [09-01|02:46:26.234] New local node record seq=1,692,616,290,686 id=2c9af1742f8f85ce ip=34.250.32.100 udp=30311 tcp=0
|
||||
```
|
||||
|
||||
## Contribution
|
||||
|
||||
Thank you for considering helping out with the source code! We welcome contributions
|
||||
|
@ -31,6 +31,7 @@ type EVMLogger interface {
|
||||
// Transaction level
|
||||
CaptureTxStart(gasLimit uint64)
|
||||
CaptureTxEnd(restGas uint64)
|
||||
CaptureSystemTxEnd(intrinsicGas uint64)
|
||||
// Top call frame
|
||||
CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int)
|
||||
CaptureEnd(output []byte, gasUsed uint64, err error)
|
||||
|
@ -91,6 +91,9 @@ type blockBroadcasterFn func(block *types.Block, propagate bool)
|
||||
// chainHeightFn is a callback type to retrieve the current chain height.
|
||||
type chainHeightFn func() uint64
|
||||
|
||||
// chainFinalizedHeightFn is a callback type to retrieve the current chain finalized height.
|
||||
type chainFinalizedHeightFn func() uint64
|
||||
|
||||
// headersInsertFn is a callback type to insert a batch of headers into the local chain.
|
||||
type headersInsertFn func(headers []*types.Header) (int, error)
|
||||
|
||||
@ -184,14 +187,15 @@ type BlockFetcher struct {
|
||||
queued map[common.Hash]*blockOrHeaderInject // Set of already queued blocks (to dedup imports)
|
||||
|
||||
// Callbacks
|
||||
getHeader HeaderRetrievalFn // Retrieves a header from the local chain
|
||||
getBlock blockRetrievalFn // Retrieves a block from the local chain
|
||||
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
|
||||
broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers
|
||||
chainHeight chainHeightFn // Retrieves the current chain's height
|
||||
insertHeaders headersInsertFn // Injects a batch of headers into the chain
|
||||
insertChain chainInsertFn // Injects a batch of blocks into the chain
|
||||
dropPeer peerDropFn // Drops a peer for misbehaving
|
||||
getHeader HeaderRetrievalFn // Retrieves a header from the local chain
|
||||
getBlock blockRetrievalFn // Retrieves a block from the local chain
|
||||
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
|
||||
broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers
|
||||
chainHeight chainHeightFn // Retrieves the current chain's height
|
||||
chainFinalizedHeight chainFinalizedHeightFn // Retrieves the current chain's finalized height
|
||||
insertHeaders headersInsertFn // Injects a batch of headers into the chain
|
||||
insertChain chainInsertFn // Injects a batch of blocks into the chain
|
||||
dropPeer peerDropFn // Drops a peer for misbehaving
|
||||
|
||||
// Testing hooks
|
||||
announceChangeHook func(common.Hash, bool) // Method to call upon adding or deleting a hash from the blockAnnounce list
|
||||
@ -202,32 +206,35 @@ type BlockFetcher struct {
|
||||
}
|
||||
|
||||
// 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, chainFinalizedHeight chainFinalizedHeightFn,
|
||||
insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn) *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{}),
|
||||
requeue: make(chan *blockOrHeaderInject),
|
||||
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{}),
|
||||
requeue: make(chan *blockOrHeaderInject),
|
||||
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,
|
||||
chainFinalizedHeight: chainFinalizedHeight,
|
||||
insertHeaders: insertHeaders,
|
||||
insertChain: insertChain,
|
||||
dropPeer: dropPeer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,6 +362,7 @@ func (f *BlockFetcher) loop() {
|
||||
}
|
||||
// Import any queued blocks that could potentially fit
|
||||
height := f.chainHeight()
|
||||
finalizedHeight := f.chainFinalizedHeight()
|
||||
for !f.queue.Empty() {
|
||||
op := f.queue.PopItem()
|
||||
hash := op.hash()
|
||||
@ -371,7 +379,7 @@ func (f *BlockFetcher) loop() {
|
||||
break
|
||||
}
|
||||
// Otherwise if fresh and still unknown, try and import
|
||||
if (number+maxUncleDist < height) || (f.light && f.getHeader(hash) != nil) || (!f.light && f.getBlock(hash) != nil) {
|
||||
if (number+maxUncleDist < height) || number <= finalizedHeight || (f.light && f.getHeader(hash) != nil) || (!f.light && f.getBlock(hash) != nil) {
|
||||
f.forgetBlock(hash)
|
||||
continue
|
||||
}
|
||||
@ -402,7 +410,13 @@ func (f *BlockFetcher) loop() {
|
||||
}
|
||||
// If we have a valid block number, check that it's potentially useful
|
||||
if dist := int64(notification.number) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist {
|
||||
log.Debug("Peer discarded announcement", "peer", notification.origin, "number", notification.number, "hash", notification.hash, "distance", dist)
|
||||
log.Debug("Peer discarded announcement by distance", "peer", notification.origin, "number", notification.number, "hash", notification.hash, "distance", dist)
|
||||
blockAnnounceDropMeter.Mark(1)
|
||||
break
|
||||
}
|
||||
finalized := f.chainFinalizedHeight()
|
||||
if notification.number <= finalized {
|
||||
log.Debug("Peer discarded announcement by finality", "peer", notification.origin, "number", notification.number, "hash", notification.hash, "finalized", finalized)
|
||||
blockAnnounceDropMeter.Mark(1)
|
||||
break
|
||||
}
|
||||
@ -803,6 +817,14 @@ func (f *BlockFetcher) enqueue(peer string, header *types.Header, block *types.B
|
||||
f.forgetHash(hash)
|
||||
return
|
||||
}
|
||||
// Discard any block that is below the current finalized height
|
||||
finalizedHeight := f.chainFinalizedHeight()
|
||||
if number <= finalizedHeight {
|
||||
log.Debug("Discarded delivered header or block, below or equal to finalized", "peer", peer, "number", number, "hash", hash, "finalized", finalizedHeight)
|
||||
blockBroadcastDropMeter.Mark(1)
|
||||
f.forgetHash(hash)
|
||||
return
|
||||
}
|
||||
// Schedule the block for future importing
|
||||
if _, ok := f.queued[hash]; !ok {
|
||||
op := &blockOrHeaderInject{origin: peer}
|
||||
|
@ -101,7 +101,9 @@ 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.chainFinalizedHeight, tester.insertHeaders,
|
||||
tester.insertChain, tester.dropPeer)
|
||||
tester.fetcher.Start()
|
||||
|
||||
return tester
|
||||
@ -143,6 +145,18 @@ func (f *fetcherTester) chainHeight() uint64 {
|
||||
return f.blocks[f.hashes[len(f.hashes)-1]].NumberU64()
|
||||
}
|
||||
|
||||
func (f *fetcherTester) chainFinalizedHeight() uint64 {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
if len(f.hashes) < 3 {
|
||||
return 0
|
||||
}
|
||||
if f.fetcher.light {
|
||||
return f.headers[f.hashes[len(f.hashes)-3]].Number.Uint64()
|
||||
}
|
||||
return f.blocks[f.hashes[len(f.hashes)-3]].NumberU64()
|
||||
}
|
||||
|
||||
// insertChain injects a new headers into the simulated chain.
|
||||
func (f *fetcherTester) insertHeaders(headers []*types.Header) (int, error) {
|
||||
f.lock.Lock()
|
||||
@ -735,6 +749,67 @@ func testDistantAnnouncementDiscarding(t *testing.T, light bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that announcements with numbers much lower or equal to the current finalized block
|
||||
// head get discarded to prevent wasting resources on useless blocks from faulty peers.
|
||||
func TestFullFinalizedAnnouncementDiscarding(t *testing.T) {
|
||||
testFinalizedAnnouncementDiscarding(t, false)
|
||||
}
|
||||
func TestLightFinalizedAnnouncementDiscarding(t *testing.T) {
|
||||
testFinalizedAnnouncementDiscarding(t, true)
|
||||
}
|
||||
|
||||
func testFinalizedAnnouncementDiscarding(t *testing.T, light bool) {
|
||||
// Create a long chain to import and define the discard boundaries
|
||||
hashes, blocks := makeChain(3*maxQueueDist, 0, genesis)
|
||||
|
||||
head := hashes[len(hashes)/2]
|
||||
justified := hashes[len(hashes)/2+1]
|
||||
finalized := hashes[len(hashes)/2+2]
|
||||
beforeFinalized := hashes[len(hashes)/2+3]
|
||||
|
||||
low, equal := len(hashes)/2+3, len(hashes)/2+2
|
||||
|
||||
// Create a tester and simulate a head block being the middle of the above chain
|
||||
tester := newTester(light)
|
||||
|
||||
tester.lock.Lock()
|
||||
tester.hashes = []common.Hash{beforeFinalized, finalized, justified, head}
|
||||
tester.headers = map[common.Hash]*types.Header{
|
||||
beforeFinalized: blocks[beforeFinalized].Header(),
|
||||
finalized: blocks[finalized].Header(),
|
||||
justified: blocks[justified].Header(),
|
||||
head: blocks[head].Header(),
|
||||
}
|
||||
tester.blocks = map[common.Hash]*types.Block{
|
||||
beforeFinalized: blocks[beforeFinalized],
|
||||
finalized: blocks[finalized],
|
||||
justified: blocks[justified],
|
||||
head: blocks[head],
|
||||
}
|
||||
tester.lock.Unlock()
|
||||
|
||||
headerFetcher := tester.makeHeaderFetcher("lower", blocks, -gatherSlack)
|
||||
bodyFetcher := tester.makeBodyFetcher("lower", blocks, 0)
|
||||
|
||||
fetching := make(chan struct{}, 2)
|
||||
tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- struct{}{} }
|
||||
|
||||
// Ensure that a block with a lower number than the finalized height is discarded
|
||||
tester.fetcher.Notify("lower", hashes[low], blocks[hashes[low]].NumberU64(), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
|
||||
select {
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
case <-fetching:
|
||||
t.Fatalf("fetcher requested stale header")
|
||||
}
|
||||
// Ensure that a block with a same number of the finalized height is discarded
|
||||
tester.fetcher.Notify("equal", hashes[equal], blocks[hashes[equal]].NumberU64(), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
|
||||
select {
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
case <-fetching:
|
||||
t.Fatalf("fetcher requested future header")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that peers announcing blocks with invalid numbers (i.e. not matching
|
||||
// the headers provided afterwards) get dropped as malicious.
|
||||
func TestFullInvalidNumberAnnouncement(t *testing.T) { testInvalidNumberAnnouncement(t, false) }
|
||||
|
@ -271,6 +271,13 @@ func newHandler(config *handlerConfig) (*handler, error) {
|
||||
heighter := func() uint64 {
|
||||
return h.chain.CurrentBlock().Number.Uint64()
|
||||
}
|
||||
finalizeHeighter := func() uint64 {
|
||||
fblock := h.chain.CurrentFinalBlock()
|
||||
if fblock == nil {
|
||||
return 0
|
||||
}
|
||||
return fblock.Number.Uint64()
|
||||
}
|
||||
inserter := func(blocks types.Blocks) (int, error) {
|
||||
// All the block fetcher activities should be disabled
|
||||
// after the transition. Print the warning log.
|
||||
@ -324,7 +331,8 @@ 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, finalizeHeighter, nil, inserter, h.removePeer)
|
||||
|
||||
fetchTx := func(peer string, hashes []common.Hash) error {
|
||||
p := h.peers.peer(peer)
|
||||
|
@ -995,6 +995,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||
}()
|
||||
defer cancel()
|
||||
|
||||
var intrinsicGas uint64 = 0
|
||||
// Run the transaction with tracing enabled.
|
||||
if posa, ok := api.backend.Engine().(consensus.PoSA); ok && message.From == vmctx.Coinbase &&
|
||||
posa.IsSystemContract(message.To) && message.GasPrice.Cmp(big.NewInt(0)) == 0 {
|
||||
@ -1003,6 +1004,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||
statedb.SetBalance(consensus.SystemAddress, big.NewInt(0))
|
||||
statedb.AddBalance(vmctx.Coinbase, balance)
|
||||
}
|
||||
intrinsicGas, _ = core.IntrinsicGas(message.Data, message.AccessList, false, true, true, false)
|
||||
}
|
||||
|
||||
// Call Prepare to clear out the statedb access list
|
||||
@ -1010,6 +1012,7 @@ func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Conte
|
||||
if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit)); err != nil {
|
||||
return nil, fmt.Errorf("tracing failed: %w", err)
|
||||
}
|
||||
tracer.CaptureSystemTxEnd(intrinsicGas)
|
||||
return tracer.GetResult()
|
||||
}
|
||||
|
||||
|
@ -222,6 +222,8 @@ func (t *jsTracer) CaptureTxEnd(restGas uint64) {
|
||||
t.ctx["gasUsed"] = t.vm.ToValue(t.gasLimit - restGas)
|
||||
}
|
||||
|
||||
func (t *jsTracer) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// CaptureStart implements the Tracer interface to initialize the tracing operation.
|
||||
func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
t.env = env
|
||||
|
@ -172,6 +172,8 @@ func (*AccessListTracer) CaptureTxStart(gasLimit uint64) {}
|
||||
|
||||
func (*AccessListTracer) CaptureTxEnd(restGas uint64) {}
|
||||
|
||||
func (*AccessListTracer) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// AccessList returns the current accesslist maintained by the tracer.
|
||||
func (a *AccessListTracer) AccessList() types.AccessList {
|
||||
return a.list.accessList()
|
||||
|
@ -269,6 +269,10 @@ func (l *StructLogger) CaptureTxEnd(restGas uint64) {
|
||||
l.usedGas = l.gasLimit - restGas
|
||||
}
|
||||
|
||||
func (l *StructLogger) CaptureSystemTxEnd(intrinsicGas uint64) {
|
||||
l.usedGas -= intrinsicGas
|
||||
}
|
||||
|
||||
// StructLogs returns the captured log entries.
|
||||
func (l *StructLogger) StructLogs() []StructLog { return l.logs }
|
||||
|
||||
@ -398,6 +402,8 @@ func (*mdLogger) CaptureTxStart(gasLimit uint64) {}
|
||||
|
||||
func (*mdLogger) CaptureTxEnd(restGas uint64) {}
|
||||
|
||||
func (*mdLogger) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// ExecutionResult groups all structured logs emitted by the EVM
|
||||
// while replaying a transaction in debug mode as well as transaction
|
||||
// execution status, the amount of gas used and the return value
|
||||
|
@ -100,3 +100,5 @@ func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}
|
||||
func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {}
|
||||
|
||||
func (l *JSONLogger) CaptureTxEnd(restGas uint64) {}
|
||||
|
||||
func (l *JSONLogger) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
@ -111,6 +111,8 @@ func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to comm
|
||||
t.store(input[0:4], len(input)-4)
|
||||
}
|
||||
|
||||
func (*fourByteTracer) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// GetResult returns the json-encoded nested list of call traces, and any
|
||||
// error arising from the encoding or forceful termination (via `Stop`).
|
||||
func (t *fourByteTracer) GetResult() (json.RawMessage, error) {
|
||||
|
@ -247,6 +247,10 @@ func (t *callTracer) CaptureTxEnd(restGas uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *callTracer) CaptureSystemTxEnd(intrinsicGas uint64) {
|
||||
t.callstack[0].GasUsed -= intrinsicGas
|
||||
}
|
||||
|
||||
// GetResult returns the json-encoded nested list of call traces, and any
|
||||
// error arising from the encoding or forceful termination (via `Stop`).
|
||||
func (t *callTracer) GetResult() (json.RawMessage, error) {
|
||||
|
@ -209,6 +209,10 @@ func (t *flatCallTracer) CaptureTxEnd(restGas uint64) {
|
||||
t.tracer.CaptureTxEnd(restGas)
|
||||
}
|
||||
|
||||
func (t *flatCallTracer) CaptureSystemTxEnd(intrinsicGas uint64) {
|
||||
t.tracer.CaptureSystemTxEnd(intrinsicGas)
|
||||
}
|
||||
|
||||
// GetResult returns an empty json object.
|
||||
func (t *flatCallTracer) GetResult() (json.RawMessage, error) {
|
||||
if len(t.tracer.callstack) < 1 {
|
||||
|
@ -113,6 +113,12 @@ func (t *muxTracer) CaptureTxEnd(restGas uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *muxTracer) CaptureSystemTxEnd(intrinsicGas uint64) {
|
||||
for _, t := range t.tracers {
|
||||
t.CaptureSystemTxEnd(intrinsicGas)
|
||||
}
|
||||
}
|
||||
|
||||
// GetResult returns an empty json object.
|
||||
func (t *muxTracer) GetResult() (json.RawMessage, error) {
|
||||
resObject := make(map[string]json.RawMessage)
|
||||
|
@ -67,6 +67,8 @@ func (*noopTracer) CaptureTxStart(gasLimit uint64) {}
|
||||
|
||||
func (*noopTracer) CaptureTxEnd(restGas uint64) {}
|
||||
|
||||
func (*noopTracer) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// GetResult returns an empty json object.
|
||||
func (t *noopTracer) GetResult() (json.RawMessage, error) {
|
||||
return json.RawMessage(`{}`), nil
|
||||
|
@ -246,6 +246,8 @@ func (t *prestateTracer) CaptureTxEnd(restGas uint64) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *prestateTracer) CaptureSystemTxEnd(intrinsicGas uint64) {}
|
||||
|
||||
// GetResult returns the json-encoded nested list of call traces, and any
|
||||
// error arising from the encoding or forceful termination (via `Stop`).
|
||||
func (t *prestateTracer) GetResult() (json.RawMessage, error) {
|
||||
|
1
go.mod
1
go.mod
@ -245,6 +245,7 @@ require (
|
||||
github.com/schollz/progressbar/v3 v3.3.4 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/supranational/blst v0.3.11 // indirect
|
||||
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect
|
||||
github.com/tidwall/gjson v1.10.2 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
|
@ -19,13 +19,15 @@ package params
|
||||
import "github.com/ethereum/go-ethereum/common"
|
||||
|
||||
// MainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on
|
||||
// the main Ethereum network.
|
||||
// the main BSC network.
|
||||
var MainnetBootnodes = []string{
|
||||
// Ethereum Foundation Go Bootnodes
|
||||
"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", // bootnode-aws-ap-southeast-1-001
|
||||
"enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", // bootnode-aws-us-east-1-001
|
||||
"enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303", // bootnode-hetzner-hel
|
||||
"enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn
|
||||
// BNB chain Go Bootnodes
|
||||
"enode://433c8bfdf53a3e2268ccb1b829e47f629793291cbddf0c76ae626da802f90532251fc558e2e0d10d6725e759088439bf1cd4714716b03a259a35d4b2e4acfa7f@52.69.102.73:30311",
|
||||
"enode://571bee8fb902a625942f10a770ccf727ae2ba1bab2a2b64e121594a99c9437317f6166a395670a00b7d93647eacafe598b6bbcef15b40b6d1a10243865a3e80f@35.73.84.120:30311",
|
||||
"enode://fac42fb0ba082b7d1eebded216db42161163d42e4f52c9e47716946d64468a62da4ba0b1cac0df5e8bf1e5284861d757339751c33d51dfef318be5168803d0b5@18.203.152.54:30311",
|
||||
"enode://3063d1c9e1b824cfbb7c7b6abafa34faec6bb4e7e06941d218d760acdd7963b274278c5c3e63914bd6d1b58504c59ec5522c56f883baceb8538674b92da48a96@34.250.32.100:30311",
|
||||
"enode://ad78c64a4ade83692488aa42e4c94084516e555d3f340d9802c2bf106a3df8868bc46eae083d2de4018f40e8d9a9952c32a0943cd68855a9bc9fd07aac982a6d@34.204.214.24:30311",
|
||||
"enode://5db798deb67df75d073f8e2953dad283148133acb520625ea804c9c4ad09a35f13592a762d8f89056248f3889f6dcc33490c145774ea4ff2966982294909b37a@107.20.191.97:30311",
|
||||
}
|
||||
|
||||
var V5Bootnodes = []string{
|
||||
|
Loading…
Reference in New Issue
Block a user