mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-21 06:04:33 +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/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/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/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
M2ByteLength = 4
|
||||
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
|
||||
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
|
||||
)
|
||||
|
||||
type rewardLog struct {
|
||||
|
|
@ -41,8 +42,11 @@ type rewardLog struct {
|
|||
Reward *big.Int `json:"reward"`
|
||||
}
|
||||
|
||||
var TxSignMu sync.RWMutex
|
||||
// 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 {
|
||||
TxSignMu.Lock()
|
||||
defer TxSignMu.Unlock()
|
||||
if chainConfig.XDPoS != nil {
|
||||
// Find active account.
|
||||
account := accounts.Account{}
|
||||
|
|
@ -65,7 +69,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
// Add tx signed to local tx pool.
|
||||
err = pool.AddLocal(txSigned)
|
||||
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.
|
||||
|
|
@ -93,7 +97,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
// Add tx signed to local tx pool.
|
||||
err = pool.AddLocal(txSigned)
|
||||
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.
|
||||
|
|
@ -120,7 +124,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
// Add tx to pool.
|
||||
err = pool.AddLocal(txSigned)
|
||||
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.
|
||||
|
|
@ -241,30 +245,13 @@ func BuildValidatorFromM2(listM2 []int64) []byte {
|
|||
var validatorBytes []byte
|
||||
for _, numberM2 := range listM2 {
|
||||
// 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...)
|
||||
}
|
||||
|
||||
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.
|
||||
func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
|
||||
validatorsByte, err := hexutil.Decode(validatorsStr)
|
||||
|
|
@ -272,7 +259,7 @@ func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return ExtractValidatorsFromBytes(validatorsByte), nil
|
||||
return XDPoS.ExtractValidatorsFromBytes(validatorsByte), nil
|
||||
}
|
||||
|
||||
// Decrypt randomize from secrets and opening.
|
||||
|
|
@ -542,34 +529,4 @@ func isInt(strNumber string) bool {
|
|||
} else {
|
||||
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