diff --git a/contracts/utils.go b/contracts/utils.go index 8b5c8e4d69..fd6615e4de 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -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 -} +} \ No newline at end of file