Skip to content

Commit

Permalink
Merge pull request #1777 from bnb-chain/develop
Browse files Browse the repository at this point in the history
release: draft release v1.2.9
  • Loading branch information
brilliant-lx authored Jul 21, 2023
2 parents 5f87ddf + 83cc950 commit 34b065a
Show file tree
Hide file tree
Showing 25 changed files with 322 additions and 79 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Changelog
## v1.2.9
FEATURE
* [\#1775](https://github.com/bnb-chain/bsc/pull/1775) upgrade: several hardfork block height on mainnet: Plato, Hertz(Berlin, London)

## v1.2.8
FEATURE
* [\#1626](https://github.com/bnb-chain/bsc/pull/1626) eth/filters, ethclient/gethclient: add fullTx option to pending tx filter
Expand Down
1 change: 1 addition & 0 deletions cmd/bootnode/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ func main() {
PrivateKey: nodeKey,
NetRestrict: restrictList,
FilterFunction: filterFunction,
IsBootnode: true,
}
if *runv5 {
if _, err := discover.ListenV5(conn, ln, cfg); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const (

systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system

collectAdditionalVotesRewardRatio = float64(1) // ratio of additional reward for collecting more votes than needed
collectAdditionalVotesRewardRatio = 100 // ratio of additional reward for collecting more votes than needed, the denominator is 100
)

var (
Expand Down Expand Up @@ -1027,7 +1027,7 @@ func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, sta
}
quorum := cmath.CeilDiv(len(snap.Validators)*2, 3)
if validVoteCount > quorum {
accumulatedWeights[head.Coinbase] += uint64(float64(validVoteCount-quorum) * collectAdditionalVotesRewardRatio)
accumulatedWeights[head.Coinbase] += uint64((validVoteCount - quorum) * collectAdditionalVotesRewardRatio / 100)
}
}

Expand Down Expand Up @@ -1788,7 +1788,7 @@ func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) {
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader
header.Extra[:len(header.Extra)-extraSeal], // this will panic if extra is too short, should check before calling encodeSigHeader
header.MixDigest,
header.Nonce,
})
Expand Down
14 changes: 7 additions & 7 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
// If the transaction is already known, discard it
hash := tx.Hash()
if pool.all.Get(hash) != nil {
//log.Trace("Discarding already known transaction", "hash", hash)
log.Trace("Discarding already known transaction", "hash", hash)
knownTxMeter.Mark(1)
return false, ErrAlreadyKnown
}
Expand All @@ -737,7 +737,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e

// If the transaction fails basic validation, discard it
if err := pool.validateTx(tx, isLocal); err != nil {
//log.Trace("Discarding invalid transaction", "hash", hash, "err", err)
log.Trace("Discarding invalid transaction", "hash", hash, "err", err)
invalidTxMeter.Mark(1)
return false, err
}
Expand All @@ -749,7 +749,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
// If the new transaction is underpriced, don't accept it
if !isLocal && pool.priced.Underpriced(tx) {
//log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
underpricedTxMeter.Mark(1)
return false, ErrUnderpriced
}
Expand All @@ -770,7 +770,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e

// Special case, we still can't make the room for the new remote one.
if !isLocal && !success {
//log.Trace("Discarding overflown transaction", "hash", hash)
log.Trace("Discarding overflown transaction", "hash", hash)
overflowedTxMeter.Mark(1)
return false, ErrTxPoolOverflow
}
Expand All @@ -797,7 +797,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e

// Kick out the underpriced remote transactions.
for _, tx := range drop {
//log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
underpricedTxMeter.Mark(1)
dropped := pool.removeTx(tx.Hash(), false)
pool.changesSinceReorg += dropped
Expand All @@ -822,7 +822,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
pool.priced.Put(tx, isLocal)
pool.journalTx(from, tx)
pool.queueTxEvent(tx)
//log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())

// Successful promotion, bump the heartbeat
pool.beats[from] = time.Now()
Expand All @@ -844,7 +844,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
}
pool.journalTx(from, tx)

//log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
return replaced, nil
}

Expand Down
2 changes: 2 additions & 0 deletions eth/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,8 @@ func (h *handler) voteBroadcastLoop() {
for {
select {
case event := <-h.voteCh:
// The timeliness of votes is very important,
// so one vote will be sent instantly without waiting for other votes for batch sending by design.
h.BroadcastVote(event.Vote)
case <-h.votesSub.Err():
return
Expand Down
12 changes: 9 additions & 3 deletions eth/handler_bsc.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,15 @@ func (h *bscHandler) Handle(peer *bsc.Peer, packet bsc.Packet) error {
// handleVotesBroadcast is invoked from a peer's message handler when it transmits a
// votes broadcast for the local node to process.
func (h *bscHandler) handleVotesBroadcast(peer *bsc.Peer, votes []*types.VoteEnvelope) error {
// Try to put votes into votepool
for _, vote := range votes {
h.votepool.PutVote(vote)
if peer.IsOverLimitAfterReceiving() {
peer.Log().Warn("peer sending votes too much, votes dropped; it may be a ddos attack, please check!")
return nil
}
// Here we only put the first vote, to avoid ddos attack by sending a large batch of votes.
// This won't abandon any valid vote, because one vote is sent every time referring to func voteBroadcastLoop
if len(votes) > 0 {
h.votepool.PutVote(votes[0])
}

return nil
}
27 changes: 27 additions & 0 deletions eth/protocols/bsc/peer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package bsc

import (
"time"

mapset "github.com/deckarep/golang-set"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -16,6 +18,15 @@ const (

// voteBufferSize is the maximum number of batch votes can be hold before sending
voteBufferSize = 21 * 2

// used to avoid of DDOS attack
// It's the max number of received votes per second from one peer
// 21 validators exist now, so 21 votes will be produced every one block interval
// so the limit is 7 = 21/3, here set it to 10 with a buffer.
receiveRateLimitPerSecond = 10

// the time span of one period
secondsPerPeriod = float64(10)
)

// max is a helper function which returns the larger of the two given integers.
Expand All @@ -31,6 +42,8 @@ type Peer struct {
id string // Unique ID for the peer, cached
knownVotes *knownCache // Set of vote hashes known to be known by this peer
voteBroadcast chan []*types.VoteEnvelope // Channel used to queue votes propagation requests
periodBegin time.Time // Begin time of the latest period for votes counting
periodCounter uint // Votes number in the latest period

*p2p.Peer // The embedded P2P package peer
rw p2p.MsgReadWriter // Input/output streams for bsc
Expand All @@ -47,6 +60,8 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
id: id,
knownVotes: newKnownCache(maxKnownVotes),
voteBroadcast: make(chan []*types.VoteEnvelope, voteBufferSize),
periodBegin: time.Now(),
periodCounter: 0,
Peer: p,
rw: rw,
version: version,
Expand Down Expand Up @@ -114,6 +129,18 @@ func (p *Peer) AsyncSendVotes(votes []*types.VoteEnvelope) {
}
}

// Step into the next period when secondsPerPeriod seconds passed,
// Otherwise, check whether the number of received votes extra (secondsPerPeriod * receiveRateLimitPerSecond)
func (p *Peer) IsOverLimitAfterReceiving() bool {
if timeInterval := time.Since(p.periodBegin).Seconds(); timeInterval >= secondsPerPeriod {
p.periodBegin = time.Now()
p.periodCounter = 0
return false
}
p.periodCounter += 1
return p.periodCounter > uint(secondsPerPeriod*receiveRateLimitPerSecond)
}

// broadcastVotes is a write loop that schedules votes broadcasts
// to the remote peer. The goal is to have an async writer that does not lock up
// node internals and at the same time rate limits queued data.
Expand Down
6 changes: 4 additions & 2 deletions eth/tracers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,8 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
return nil, err
}
}
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true})

// Define a meaningful timeout of a single transaction trace
if config.Timeout != nil {
if timeout, err = time.ParseDuration(*config.Timeout); err != nil {
Expand All @@ -919,13 +921,13 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
<-deadlineCtx.Done()
if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
tracer.Stop(errors.New("execution timeout"))
// Stop evm execution. Note cancellation is not necessarily immediate.
vmenv.Cancel()
}
}()
defer cancel()

// Run the transaction with tracing enabled.
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true})

if posa, ok := api.backend.Engine().(consensus.PoSA); ok && message.From() == vmctx.Coinbase &&
posa.IsSystemContract(message.To()) && message.GasPrice().Cmp(big.NewInt(0)) == 0 {
balance := statedb.GetBalance(consensus.SystemAddress)
Expand Down
1 change: 0 additions & 1 deletion eth/tracers/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common.
func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
// If tracing was interrupted, set the error and stop
if atomic.LoadUint32(&l.interrupt) > 0 {
l.env.Cancel()
return
}
// check if already accumulated the specified number of logs
Expand Down
4 changes: 0 additions & 4 deletions eth/tracers/native/4byte.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ func init() {
// 0xc281d19e-0: 1
// }
type fourByteTracer struct {
env *vm.EVM
ids map[string]int // ids aggregates the 4byte ids found
interrupt uint32 // Atomic flag to signal execution interruption
reason error // Textual reason for the interruption
Expand Down Expand Up @@ -80,8 +79,6 @@ func (t *fourByteTracer) store(id []byte, size int) {

// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
t.env = env

// Update list of precompiles based on current block
rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil)
t.activePrecompiles = vm.ActivePrecompiles(rules)
Expand All @@ -100,7 +97,6 @@ func (t *fourByteTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64,
func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
// Skip if tracing was interrupted
if atomic.LoadUint32(&t.interrupt) > 0 {
t.env.Cancel()
return
}
if len(input) < 4 {
Expand Down
138 changes: 138 additions & 0 deletions eth/tracers/native/mux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package native

import (
"encoding/json"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/tracers"
)

func init() {
register("muxTracer", newMuxTracer)
}

// muxTracer is a go implementation of the Tracer interface which
// runs multiple tracers in one go.
type muxTracer struct {
names []string
tracers []tracers.Tracer
}

// newMuxTracer returns a new mux tracer.
func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
var config map[string]json.RawMessage
if cfg != nil {
if err := json.Unmarshal(cfg, &config); err != nil {
return nil, err
}
}
objects := make([]tracers.Tracer, 0, len(config))
names := make([]string, 0, len(config))
for k, v := range config {
t, err := tracers.New(k, ctx, v)
if err != nil {
return nil, err
}
objects = append(objects, t)
names = append(names, k)
}

return &muxTracer{names: names, tracers: objects}, nil
}

// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (t *muxTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
for _, t := range t.tracers {
t.CaptureStart(env, from, to, create, input, gas, value)
}
}

// CaptureEnd is called after the call finishes to finalize the tracing.
func (t *muxTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
for _, t := range t.tracers {
t.CaptureEnd(output, gasUsed, err)
}
}

// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
for _, t := range t.tracers {
t.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
}
}

// CaptureFault implements the EVMLogger interface to trace an execution fault.
func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
for _, t := range t.tracers {
t.CaptureFault(pc, op, gas, cost, scope, depth, err)
}
}

// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
func (t *muxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
for _, t := range t.tracers {
t.CaptureEnter(typ, from, to, input, gas, value)
}
}

// CaptureExit is called when EVM exits a scope, even if the scope didn't
// execute any code.
func (t *muxTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
for _, t := range t.tracers {
t.CaptureExit(output, gasUsed, err)
}
}

func (t *muxTracer) CaptureTxStart(gasLimit uint64) {
for _, t := range t.tracers {
t.CaptureTxStart(gasLimit)
}
}

func (t *muxTracer) CaptureTxEnd(restGas uint64) {
for _, t := range t.tracers {
t.CaptureTxEnd(restGas)
}
}

// GetResult returns an empty json object.
func (t *muxTracer) GetResult() (json.RawMessage, error) {
resObject := make(map[string]json.RawMessage)
for i, tt := range t.tracers {
r, err := tt.GetResult()
if err != nil {
return nil, err
}
resObject[t.names[i]] = r
}
res, err := json.Marshal(resObject)
if err != nil {
return nil, err
}
return res, nil
}

// Stop terminates execution of the tracer at the first opportune moment.
func (t *muxTracer) Stop(err error) {
for _, t := range t.tracers {
t.Stop(err)
}
}
Loading

0 comments on commit 34b065a

Please sign in to comment.