Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft release v1.2.10 #1793

Merged
merged 9 commits into from
Aug 3, 2023
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
# Changelog
## v1.2.10
FEATURE
* [\#1780](https://github.com/bnb-chain/bsc/pull/1780) log: reduce logs when receiving too much votes from a peer
* [\#1788](https://github.com/bnb-chain/bsc/pull/1788) metrics: add txpool config into metrics server
* [\#1789](https://github.com/bnb-chain/bsc/pull/1789) rpc: add GetFinalizedHeader/Block to simplify using the fast finality feature
* [\#1791](https://github.com/bnb-chain/bsc/pull/1791) finality: add more check to ensure result of assembleVoteAttestation

BUGFIX
* [\#1773](https://github.com/bnb-chain/bsc/pull/1773) discov: do not filter out bootnodes
* [\#1778](https://github.com/bnb-chain/bsc/pull/1778) vote: backup validator sync votes from corresponding mining validator
* [\#1784](https://github.com/bnb-chain/bsc/pull/1784) fix: exclude same votes when doing malicious voting check

## v1.2.9
FEATURE
* [\#1775](https://github.com/bnb-chain/bsc/pull/1775) upgrade: several hardfork block height on mainnet: Plato, Hertz(Berlin, London)
Expand Down
108 changes: 108 additions & 0 deletions cmd/extradump/extradump_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package main

import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
)

func TestExtraParse(t *testing.T) {
// case 1, |---Extra Vanity---|---Empty---|---Empty---|---Extra Seal---|
{
extraData := "0xd983010209846765746889676f312e31392e3131856c696e75780000a6bf97c1e99f701bb14cb7dfb68b90bd3e6d1ca656964630de71beffc7f33f7f08ec99d336ec51ad9fad0ac84ae77ca2e8ad9512acc56e0d7c93f3c2ce7de1b69149a5a400"
_, err := parseExtra(extraData)
assert.NoError(t, err)
}

// case 2, |---Extra Vanity---|---Validators Number and Validators Bytes---|---Empty---|---Extra Seal---|
{
extraData := "0xd983010209846765746889676f312e31392e3131856c696e75780000a6bf97c1152465176c461afb316ebc773c61faee85a6515daa8a923564c6ffd37fb2fe9f118ef88092e8762c7addb526ab7eb1e772baef85181f892c731be0c1891a50e6b06262c816295e26495cef6f69dfa69911d9d8e4f3bbadb89b977cf58294f7239d515e15b24cfeb82494056cf691eaf729b165f32c9757c429dba5051155903067e56ebe3698678e912d4c407bbe49438ed859fe965b140dcf1aab71a993c1f7f6929d1fe2a17b4e14614ef9fc5bdc713d6631d675403fbeefac55611bf612700b1b65f4744861b80b0f7d6ab03f349bbafec1551819b8be1efea2fc46ca749aa184248a459464eec1a21e7fc7b71a053d9644e9bb8da4853b8f872cd7c1d6b324bf1922829830646ceadfb658d3de009a61dd481a114a2e761c554b641742c973867899d300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069c77a677c40c7fbea129d4b171a39b7a8ddabfab2317f59d86abfaf690850223d90e9e7593d91a29331dfc2f84d5adecc75fc39ecab4632c1b4400a3dd1e1298835bcca70f657164e5b75689b64b7fd1fa275f334f28e1896a26afa1295da81418593bd12814463d9f6e45c36a0e47eb4cd3e5b6af29c41e2a3a5636430155a466e216585af3ba772b61c6014342d914470ec7ac2975be345796c2b81db0422a5fd08e40db1fc2368d2245e4b18b1d0b85c921aaaafd2e341760e29fc613edd39f71254614e2055c3287a517ae2f5b9e386cd1b50a4550696d957cb4900f03ab84f83ff2df44193496793b847f64e9d6db1b3953682bb95edd096eb1e69bbd357c200992ca78050d0cbe180cfaa018e8b6c8fd93d6f4cea42bbb345dbc6f0dfdb5bec73a8a257074e82b881cfa06ef3eb4efeca060c2531359abd0eab8af1e3edfa2025fca464ac9c3fd123f6c24a0d78869485a6f79b60359f141df90a0c745125b131caaffd12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b218c5d6af1f979ac42bc68d98a5a0d796c6ab01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4dd66d7c2c7e57f628210187192fb89d4b99dd4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be807dddb074639cd9fa61b47676c064fc50d62cb1f2c71577def3144fabeb75a8a1c8cb5b51d1d1b4a05eec67988b8685008baa17459ec425dbaebc852f496dc92196cdcc8e6d00c17eb431350c6c50d8b8f05176b90b11b3a3d4feb825ae9702711566df5dbf38e82add4dd1b573b95d2466fa6501ccb81e9d26a352b96150ccbf7b697fd0a419d1d6bf74282782b0b3eb1413c901d6ecf02e8e28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2d3a739effcd3a99387d015e260eefac72ebea1956c470ddff48cb49300200b5f83497f3a3ccb3aeb83c5edd9818569038e61d197184f4aa6939ea5e9911e3e98ac6d21e9ae3261a475a27bb1028f140bc2a7c843318afd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0a6e3c511bbd10f4519ece37dc24887e11b55db2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183ee226379db83cffc681495730c11fdde79ba4c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef0274e31810c9df02f98fafde0f841f4e66a1cd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e99f701bb14cb7dfb68b90bd3e6d1ca656964630de71beffc7f33f7f08ec99d336ec51ad9fad0ac84ae77ca2e8ad9512acc56e0d7c93f3c2ce7de1b69149a5a400"
extra, err := parseExtra(extraData)
assert.NoError(t, err)
{
var have = extra.ValidatorSize
var want = uint8(21)
if have != want {
t.Fatalf("extra.ValidatorSize mismatch, have %d, want %d", have, want)
}
}
{
var have = common.Bytes2Hex(extra.Validators[14].Address[:])
var want = "cc8e6d00c17eb431350c6c50d8b8f05176b90b11"
if have != want {
t.Fatalf("extra.Validators[14].Address mismatch, have %s, want %s", have, want)
}
}
{
var have = common.Bytes2Hex(extra.Validators[18].BLSPublicKey[:])
var want = "b2d4c6283c44a1c7bd503aaba7666e9f0c830e0ff016c1c750a5e48757a713d0836b1cabfd5c281b1de3b77d1c192183"
if have != want {
t.Fatalf("extra.Validators[18].BLSPublicKey mismatch, have %s, want %s", have, want)
}
}
}

// case 3, |---Extra Vanity---|---Empty---|---Vote Attestation---|---Extra Seal---|
{
extraData := "0xd883010205846765746888676f312e32302e35856c696e75780000002995c52af8b5830563efb86089cf168dcf4c5d3cb057926628ad1bf0f03ea67eef1458485578a4f8489afa8a853ecc7af45e2d145c21b70641c4b29f0febd2dd2c61fa1ba174be3fd47f1f5fa2ab9b5c318563d8b70ca58d0d51e79ee32b2fb721649e2cb9d36538361fba11f84c8401d14bb7a0fa67ddb3ba654d6006bf788710032247aa4d1be0707273e696b422b3ff72e9798401d14bbaa01225f505f5a0e1aefadcd2913b7aac9009fe4fb3d1bf57399e0b9dce5947f94280fe6d3647276c4127f437af59eb7c7985b2ae1ebe432619860695cb6106b80cc66c735bc1709afd11f233a2c97409d38ebaf7178aa53e895aea2fe0a229f71ec601"
extra, err := parseExtra(extraData)
assert.NoError(t, err)
{
var have = common.Bytes2Hex(extra.Data.TargetHash[:])
var want = "1225f505f5a0e1aefadcd2913b7aac9009fe4fb3d1bf57399e0b9dce5947f942"
if have != want {
t.Fatalf("extra.Data.TargetHash mismatch, have %s, want %s", have, want)
}
}
{
var have = extra.Data.TargetNumber
var want = uint64(30493626)
if have != want {
t.Fatalf("extra.Data.TargetNumber mismatch, have %d, want %d", have, want)
}
}
}

// case 4, |---Extra Vanity---|---Validators Number and Validators Bytes---|---Vote Attestation---|---Extra Seal---|
{
extraData := "0xd883010209846765746888676f312e31392e38856c696e7578000000dc55905c071284214b9b9c85549ab3d2b972df0deef66ac2c98e82934ca974fdcd97f3309de967d3c9c43fa711a8d673af5d75465844bf8969c8d1948d903748ac7b8b1720fa64e50c35552c16704d214347f29fa77f77da6d75d7c752b742ad4855bae330426b823e742da31f816cc83bc16d69a9134be0cfb4a1d17ec34f1b5b32d5c20440b8536b1e88f0f247788386d0ed6c748e03a53160b4b30ed3748cc5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000980a75ecd1309ea12fa2ed87a8744fbfc9b863d589037a9ace3b590165ea1c0c5ac72bf600b7c88c1e435f41932c1132aae1bfa0bb68e46b96ccb12c3415e4d82af717d8a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0b973c2d38487e58fd6e145491b110080fb14ac915a0411fc78f19e09a399ddee0d20c63a75d8f930f1694544ad2dc01bb71b214cb885500844365e95cd9942c7276e7fd8a2750ec6dded3dcdc2f351782310b0eadc077db59abca0f0cd26776e2e7acb9f3bce40b1fa5221fd1561226c6263cc5ff474cf03cceff28abc65c9cbae594f725c80e12d96c9b86c3400e529bfe184056e257c07940bb664636f689e8d2027c834681f8f878b73445261034e946bb2d901b4b878f8b27bb8608c11016739b3f8a19e54ab8c7abacd936cfeba200f3645a98b65adb0dd3692b69ce0b3ae10e7176b9a4b0d83f04065b1042b4bcb646a34b75c550f92fc34b8b2b1db0fa0d3172db23ba92727c80bcd306320d0ff411bf858525fde13bc8e0370f84c8401e9c2e6a0820dc11d63176a0eb1b828bc5376867b275579112b7013358da40317e7bab6e98401e9c2e7a00edc71ce80105a3220a87bea2792fa340d66c59002f02b0a09349ed1ed284070808b972fac2b9077a4dcb6fc37093799a652858016c99142b227500c844fa97ec22e3f9d3b1e982f14bcd999a7453e89ce5ef5c55f1c7f8f74ba904186cd67828200"
extra, err := parseExtra(extraData)
assert.NoError(t, err)
{
var have = common.Bytes2Hex(extra.Validators[0].Address[:])
var want = "1284214b9b9c85549ab3d2b972df0deef66ac2c9"
if have != want {
t.Fatalf("extra.Validators[0].Address mismatch, have %s, want %s", have, want)
}
}
{
var have = common.Bytes2Hex(extra.Validators[0].BLSPublicKey[:])
var want = "8e82934ca974fdcd97f3309de967d3c9c43fa711a8d673af5d75465844bf8969c8d1948d903748ac7b8b1720fa64e50c"
if have != want {
t.Fatalf("extra.Validators[0].BLSPublicKey mismatch, have %s, want %s", have, want)
}
}
{
var have = extra.Validators[0].VoteIncluded
var want = true
if have != want {
t.Fatalf("extra.Validators[0].VoteIncluded mismatch, have %t, want %t", have, want)
}
}
{
var have = common.Bytes2Hex(extra.Data.TargetHash[:])
var want = "0edc71ce80105a3220a87bea2792fa340d66c59002f02b0a09349ed1ed284070"
if have != want {
t.Fatalf("extra.Data.TargetHash mismatch, have %s, want %s", have, want)
}
}
{
var have = extra.Data.TargetNumber
var want = uint64(32096999)
if have != want {
t.Fatalf("extra.Data.TargetNumber mismatch, have %d, want %d", have, want)
}
}
}
}
162 changes: 162 additions & 0 deletions cmd/extradump/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright 2023 The bsc Authors
// This file is part of bsc.
package main

import (
"bytes"
"encoding/hex"
"flag"
"fmt"
"os"
"sort"
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/willf/bitset"
)

// follow define in parlia
const (
AddressLength = 20
BLSPublicKeyLength = 48

// follow order in extra field
// |---Extra Vanity---|---Validators Number and Validators Bytes (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---|
extraVanityLength = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
validatorNumberSize = 1 // Fixed number of extra prefix bytes reserved for validator number after Luban
validatorBytesLength = common.AddressLength + types.BLSPublicKeyLength
extraSealLength = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
)

type Extra struct {
ExtraVanity string
ValidatorSize uint8
Validators validatorsAscending
*types.VoteAttestation
ExtraSeal []byte
}

type ValidatorInfo struct {
common.Address
types.BLSPublicKey
VoteIncluded bool
}

// validatorsAscending implements the sort interface to allow sorting a list of ValidatorInfo
type validatorsAscending []ValidatorInfo

func (s validatorsAscending) Len() int { return len(s) }
func (s validatorsAscending) Less(i, j int) bool {
return bytes.Compare(s[i].Address[:], s[j].Address[:]) < 0
}
func (s validatorsAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func init() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "[extraHexData]")
flag.PrintDefaults()
fmt.Fprintln(os.Stderr, `
Dumps extra info from the given hex data, only support extra after luban upgrade.`)
}
}

func main() {
flag.Parse()
extraHexData := os.Args[1]
if extra, err := parseExtra(extraHexData); err == nil {
fmt.Println("extra parsed successly")
prettyExtra(*extra)
} else {
fmt.Println("extra parsed failed", "err", err)
}
}

// parseExtra parse hex data into type Extra
func parseExtra(hexData string) (*Extra, error) {
// decode hex into bytes
data, err := hex.DecodeString(strings.TrimPrefix(hexData, "0x"))
if err != nil {
return nil, fmt.Errorf("invalid hex data")
}

// parse ExtraVanity and ExtraSeal
dataLength := len(data)
var extra Extra
if dataLength < extraVanityLength+extraSealLength {
fmt.Println("length less than min required")
}
extra.ExtraVanity = string(data[:extraVanityLength])
extra.ExtraSeal = data[dataLength-extraSealLength:]
data = data[extraVanityLength : dataLength-extraSealLength]
dataLength = len(data)

// parse Validators and Vote Attestation
if dataLength > 0 {
// parse Validators
if data[0] != '\xf8' { // rlp format of attestation begin with 'f8'
validatorNum := int(data[0])
validatorBytesTotalLength := validatorNumberSize + validatorNum*validatorBytesLength
if dataLength < validatorBytesTotalLength {
return nil, fmt.Errorf("parse validators failed")
}
extra.ValidatorSize = uint8(validatorNum)
data = data[validatorNumberSize:]
for i := 0; i < validatorNum; i++ {
var validatorInfo ValidatorInfo
validatorInfo.Address = common.BytesToAddress(data[i*validatorBytesLength : i*validatorBytesLength+common.AddressLength])
copy(validatorInfo.BLSPublicKey[:], data[i*validatorBytesLength+common.AddressLength:(i+1)*validatorBytesLength])
extra.Validators = append(extra.Validators, validatorInfo)
}
sort.Sort(extra.Validators)
data = data[validatorBytesTotalLength-validatorNumberSize:]
dataLength = len(data)
}

// parse Vote Attestation
if dataLength > 0 {
if err := rlp.Decode(bytes.NewReader(data), &extra.VoteAttestation); err != nil {
return nil, fmt.Errorf("parse voteAttestation failed")
}
if extra.ValidatorSize > 0 {
validatorsBitSet := bitset.From([]uint64{uint64(extra.VoteAddressSet)})
for i := 0; i < int(extra.ValidatorSize); i++ {
if validatorsBitSet.Test(uint(i)) {
extra.Validators[i].VoteIncluded = true
}
}
}
}
}

return &extra, nil
}

// prettyExtra print Extra with a pretty format
func prettyExtra(extra Extra) {
fmt.Printf("ExtraVanity : %s\n", extra.ExtraVanity)

if extra.ValidatorSize > 0 {
fmt.Printf("ValidatorSize : %d\n", extra.ValidatorSize)
for i := 0; i < int(extra.ValidatorSize); i++ {
fmt.Printf("Validator %d\n", i+1)
fmt.Printf("\tAddress : %s\n", common.Bytes2Hex(extra.Validators[i].Address[:]))
fmt.Printf("\tVoteKey : %s\n", common.Bytes2Hex(extra.Validators[i].BLSPublicKey[:]))
fmt.Printf("\tVoteIncluded : %t\n", extra.Validators[i].VoteIncluded)
}
}

if extra.VoteAttestation != nil {
fmt.Printf("Attestation :\n")
fmt.Printf("\tVoteAddressSet : %b, %d\n", extra.VoteAddressSet, bitset.From([]uint64{uint64(extra.VoteAddressSet)}).Count())
fmt.Printf("\tAggSignature : %s\n", common.Bytes2Hex(extra.AggSignature[:]))
fmt.Printf("\tVoteData :\n")
fmt.Printf("\t\tSourceNumber : %d\n", extra.Data.SourceNumber)
fmt.Printf("\t\tSourceHash : %s\n", common.Bytes2Hex(extra.Data.SourceHash[:]))
fmt.Printf("\t\tTargetNumber : %d\n", extra.Data.TargetNumber)
fmt.Printf("\t\tTargetHash : %s\n", common.Bytes2Hex(extra.Data.TargetHash[:]))
}

fmt.Printf("ExtraSeal : %s\n", common.Bytes2Hex(extra.ExtraSeal))
}
1 change: 1 addition & 0 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
utils.SetupMetrics(ctx,
utils.EnableBuildInfo(gitCommit, gitDate),
utils.EnableMinerInfo(ctx, cfg.Eth.Miner),
utils.EnableNodeInfo(cfg.Eth.TxPool),
)
return stack, backend
}
Expand Down
15 changes: 15 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,21 @@ func EnableMinerInfo(ctx *cli.Context, minerConfig miner.Config) SetupMetricsOpt
}
}

func EnableNodeInfo(poolConfig core.TxPoolConfig) SetupMetricsOption {
return func() {
// register node info into metrics
metrics.NewRegisteredLabel("node-info", nil).Mark(map[string]interface{}{
"PriceLimit": poolConfig.PriceLimit,
"PriceBump": poolConfig.PriceBump,
"AccountSlots": poolConfig.AccountSlots,
"GlobalSlots": poolConfig.GlobalSlots,
"AccountQueue": poolConfig.AccountQueue,
"GlobalQueue": poolConfig.GlobalQueue,
"Lifetime": poolConfig.Lifetime,
})
}
}

func SetupMetrics(ctx *cli.Context, options ...SetupMetricsOption) {
if metrics.Enabled {
log.Info("Enabling metrics collection")
Expand Down
12 changes: 9 additions & 3 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,11 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1
}
}
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
if validatorsBitSet.Count() < uint(len(signatures)) {
log.Warn(fmt.Sprintf("assembleVoteAttestation, check VoteAddress Set failed, expected:%d, real:%d", len(signatures), validatorsBitSet.Count()))
return fmt.Errorf("invalid attestation, check VoteAddress Set failed")
}

// Append attestation to header extra field.
buf := new(bytes.Buffer)
Expand Down Expand Up @@ -1758,10 +1763,11 @@ func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *t
return nil
}

if snap.Attestation != nil {
return chain.GetHeader(snap.Attestation.SourceHash, snap.Attestation.SourceNumber)
if snap.Attestation == nil {
return chain.GetHeaderByNumber(0) // keep consistent with GetJustifiedNumberAndHash
}
return nil

return chain.GetHeader(snap.Attestation.SourceHash, snap.Attestation.SourceNumber)
}

// =========================== utility function ==========================
Expand Down
3 changes: 2 additions & 1 deletion core/monitor/malicious_vote_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendi
if !(blockNumber+maliciousVoteSlashScope > pendingBlockNumber) {
blockNumber = pendingBlockNumber - maliciousVoteSlashScope + 1
}
newVoteHash := newVote.Data.Hash()
for ; blockNumber <= pendingBlockNumber+upperLimitOfVoteBlockNumber; blockNumber++ {
if voteDataBuffer.Contains(blockNumber) {
voteEnvelope, ok := voteDataBuffer.Get(blockNumber)
Expand All @@ -66,7 +67,7 @@ func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendi
continue
}
maliciousVote := false
if blockNumber == targetNumber {
if blockNumber == targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.Hash() != newVoteHash {
violateRule1Counter.Inc(1)
maliciousVote = true
} else if (blockNumber < targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.SourceNumber > sourceNumber) ||
Expand Down
Loading
Loading