mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
fix error duplicate nonce when fetcher insert multi blocks
This commit is contained in:
parent
4ab15c94d3
commit
0064693228
1 changed files with 19 additions and 62 deletions
|
|
@ -8,11 +8,19 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
|
|
@ -22,18 +30,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
M2ByteLength = 4
|
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
|
||||||
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
|
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
|
||||||
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type rewardLog struct {
|
type rewardLog struct {
|
||||||
|
|
@ -41,8 +42,11 @@ type rewardLog struct {
|
||||||
Reward *big.Int `json:"reward"`
|
Reward *big.Int `json:"reward"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TxSignMu sync.RWMutex
|
||||||
// Send tx sign for block number to smart contract blockSigner.
|
// Send tx sign for block number to smart contract blockSigner.
|
||||||
func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, manager *accounts.Manager, block *types.Block, chainDb ethdb.Database) error {
|
func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, manager *accounts.Manager, block *types.Block, chainDb ethdb.Database) error {
|
||||||
|
TxSignMu.Lock()
|
||||||
|
defer TxSignMu.Unlock()
|
||||||
if chainConfig.XDPoS != nil {
|
if chainConfig.XDPoS != nil {
|
||||||
// Find active account.
|
// Find active account.
|
||||||
account := accounts.Account{}
|
account := accounts.Account{}
|
||||||
|
|
@ -65,7 +69,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
// Add tx signed to local tx pool.
|
// Add tx signed to local tx pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx sign to local pool.", "error", err)
|
log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create secret tx.
|
// Create secret tx.
|
||||||
|
|
@ -93,7 +97,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
// Add tx signed to local tx pool.
|
// Add tx signed to local tx pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx secret to local pool.", "error", err)
|
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put randomize key into chainDb.
|
// Put randomize key into chainDb.
|
||||||
|
|
@ -120,7 +124,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
// Add tx to pool.
|
// Add tx to pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to add tx opening to local pool.", "error", err)
|
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear randomize key in state db.
|
// Clear randomize key in state db.
|
||||||
|
|
@ -241,30 +245,13 @@ func BuildValidatorFromM2(listM2 []int64) []byte {
|
||||||
var validatorBytes []byte
|
var validatorBytes []byte
|
||||||
for _, numberM2 := range listM2 {
|
for _, numberM2 := range listM2 {
|
||||||
// Convert number to byte.
|
// Convert number to byte.
|
||||||
m2Byte := common.LeftPadBytes([]byte(fmt.Sprintf("%d", numberM2)), M2ByteLength)
|
m2Byte := common.LeftPadBytes([]byte(fmt.Sprintf("%d", numberM2)), XDPoS.M2ByteLength)
|
||||||
validatorBytes = append(validatorBytes, m2Byte...)
|
validatorBytes = append(validatorBytes, m2Byte...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return validatorBytes
|
return validatorBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract validators from byte array.
|
|
||||||
func ExtractValidatorsFromBytes(byteValidators []byte) []int64 {
|
|
||||||
lenValidator := len(byteValidators) / M2ByteLength
|
|
||||||
var validators []int64
|
|
||||||
for i := 0; i < lenValidator; i++ {
|
|
||||||
trimByte := bytes.Trim(byteValidators[i*M2ByteLength:(i+1)*M2ByteLength], "\x00")
|
|
||||||
intNumber, err := strconv.Atoi(string(trimByte))
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Can not convert string to integer", "error", err)
|
|
||||||
return []int64{}
|
|
||||||
}
|
|
||||||
validators = append(validators, int64(intNumber))
|
|
||||||
}
|
|
||||||
|
|
||||||
return validators
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode validator hex string.
|
// Decode validator hex string.
|
||||||
func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
|
func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
|
||||||
validatorsByte, err := hexutil.Decode(validatorsStr)
|
validatorsByte, err := hexutil.Decode(validatorsStr)
|
||||||
|
|
@ -272,7 +259,7 @@ func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ExtractValidatorsFromBytes(validatorsByte), nil
|
return XDPoS.ExtractValidatorsFromBytes(validatorsByte), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt randomize from secrets and opening.
|
// Decrypt randomize from secrets and opening.
|
||||||
|
|
@ -542,34 +529,4 @@ func isInt(strNumber string) bool {
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get masternodes address from checkpoint Header.
|
|
||||||
func GetMasternodesFromCheckpointHeader(checkpointHeader *types.Header) []common.Address {
|
|
||||||
masternodes := make([]common.Address, (len(checkpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength)
|
|
||||||
for i := 0; i < len(masternodes); i++ {
|
|
||||||
copy(masternodes[i][:], checkpointHeader.Extra[extraVanity+i*common.AddressLength:])
|
|
||||||
}
|
|
||||||
return masternodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get m2 list from checkpoint block.
|
|
||||||
func GetM1M2FromCheckpointBlock(checkpointBlock *types.Block) (map[common.Address]common.Address, error) {
|
|
||||||
if checkpointBlock.Number().Int64()%common.EpocBlockRandomize != 0 {
|
|
||||||
return nil, errors.New("This block is not checkpoint block epoc.")
|
|
||||||
}
|
|
||||||
m1m2 := map[common.Address]common.Address{}
|
|
||||||
// Get signers from this block.
|
|
||||||
masternodes := GetMasternodesFromCheckpointHeader(checkpointBlock.Header())
|
|
||||||
validators := ExtractValidatorsFromBytes(checkpointBlock.Header().Validators)
|
|
||||||
|
|
||||||
if len(validators) < len(masternodes) {
|
|
||||||
return nil, errors.New("len(m2) is less than len(m1)")
|
|
||||||
}
|
|
||||||
if len(masternodes) > 0 {
|
|
||||||
for i, m1 := range masternodes {
|
|
||||||
m1m2[m1] = masternodes[validators[i]%int64(len(masternodes))]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m1m2, nil
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue