diff --git a/common/constants.go b/common/constants.go index 842cfba422..900829a64c 100644 --- a/common/constants.go +++ b/common/constants.go @@ -23,6 +23,7 @@ const ( MergeSignRange = 15 RangeReturnSigner = 150 MinimunMinerBlockPerEpoch = 1 + IgnoreSignerCheckBlock = uint64(27307800) ) var TIP2019Block = big.NewInt(1) diff --git a/common/types.go b/common/types.go index b968b8a300..91b1ba550b 100644 --- a/common/types.go +++ b/common/types.go @@ -165,6 +165,9 @@ func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } // IsHexAddress verifies whether a string can represent a valid hex-encoded // Ethereum address or not. func IsHexAddress(s string) bool { + if hasXDCPrefix(s) { + s = s[3:] + } if hasHexPrefix(s) { s = s[2:] } @@ -196,7 +199,7 @@ func (a Address) Hex() string { result[i] -= 32 } } - return "0x" + string(result) + return "xdc" + string(result) } // String implements the stringer interface and is used also by the logger. @@ -230,7 +233,7 @@ func (a *Address) Set(other Address) { // MarshalText returns the hex representation of a. func (a Address) MarshalText() ([]byte, error) { - return hexutil.Bytes(a[:]).MarshalText() + return hexutil.Bytes(a[:]).MarshalXDCText() } // UnmarshalText parses a hash in hex syntax. diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 48b491d45c..e7979626b4 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -417,20 +417,11 @@ func (c *XDPoS) verifyCascadingFields(chain consensus.ChainReader, header *types if err == nil { return c.verifySeal(chain, header, parents, fullVerify) } - - // try again the progress with signers querying from smart contract - // for example the checkpoint is 886500 -> the start gap block is 886495 - startGapBlockHeader := header - for step := uint64(1); step <= chain.Config().XDPoS.Gap; step++ { - startGapBlockHeader = chain.GetHeader(startGapBlockHeader.ParentHash, number-step) - } - signers, err = c.HookGetSignersFromContract(startGapBlockHeader.Hash()) + signers, err = c.GetSignersFromContract(chain, header) if err != nil { - log.Debug("Can't get signers from Smart Contract ", err) return err } - err = c.checkSignersOnCheckpoint(chain, header, signers) if err == nil { return c.verifySeal(chain, header, parents, fullVerify) } @@ -440,6 +431,10 @@ func (c *XDPoS) verifyCascadingFields(chain consensus.ChainReader, header *types func (c *XDPoS) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error { number := header.Number.Uint64() + // ignore signerCheck at checkpoint block 27307800 due to wrong snapshot at gap 27307799 + if number == common.IgnoreSignerCheckBlock { + return nil + } penPenalties := []common.Address{} if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil { var err error @@ -1281,3 +1276,16 @@ func (c *XDPoS) CheckMNTurn(chain consensus.ChainReader, parent *types.Header, s } return false } + +func (c *XDPoS) GetSignersFromContract(chain consensus.ChainReader, checkpointHeader *types.Header) ([]common.Address, error) { + startGapBlockHeader := checkpointHeader + number := checkpointHeader.Number.Uint64() + for step := uint64(1); step <= chain.Config().XDPoS.Gap; step++ { + startGapBlockHeader = chain.GetHeader(startGapBlockHeader.ParentHash, number-step) + } + signers, err := c.HookGetSignersFromContract(startGapBlockHeader.Hash()) + if err != nil { + return []common.Address{}, fmt.Errorf("Can't get signers from Smart Contract . Err: %v", err) + } + return signers, nil +} diff --git a/contracts/utils.go b/contracts/utils.go index 3f563ccf7a..0ac7b06ec8 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -60,17 +60,26 @@ type rewardLog struct { 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 { +func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, manager *accounts.Manager, block *types.Block, chainDb ethdb.Database, eb common.Address) error { TxSignMu.Lock() defer TxSignMu.Unlock() if chainConfig.XDPoS != nil { // Find active account. account := accounts.Account{} var wallet accounts.Wallet + etherbaseAccount := accounts.Account{ + Address: eb, + URL: accounts.URL{}, + } if wallets := manager.Wallets(); len(wallets) > 0 { - wallet = wallets[0] - if accts := wallets[0].Accounts(); len(accts) > 0 { - account = accts[0] + if w, err := manager.Find(etherbaseAccount); err == nil && w != nil { + wallet = w + account = etherbaseAccount + } else { + wallet = wallets[0] + if accts := wallets[0].Accounts(); len(accts) > 0 { + account = accts[0] + } } } diff --git a/core/blockchain.go b/core/blockchain.go index cf6ed1f457..0b4c70f7fe 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1271,7 +1271,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty stats.processed++ stats.usedGas += usedGas stats.report(chain, i, bc.stateCache.TrieDB().Size()) - if status == CanonStatTy && bc.chainConfig.XDPoS != nil { + if bc.chainConfig.XDPoS != nil { // epoch block if (chain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 { CheckpointCh <- 1 diff --git a/eth/backend.go b/eth/backend.go index 9a71dfb752..9d5cd91f6c 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -224,7 +224,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { return nil } if block.NumberU64()%common.MergeSignRange == 0 || !eth.chainConfig.IsTIP2019(block.Number()) { - if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil { + if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb, eb); err != nil { return fmt.Errorf("Fail to create tx sign for importing block: %v", err) } } @@ -472,12 +472,14 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { sort.Slice(candidates, func(i, j int) bool { return candidates[i].Stake.Cmp(candidates[j].Stake) >= 0 }) - candidates = candidates[:150] + if len(candidates) > 150 { + candidates = candidates[:150] + } result := []common.Address{} for _, candidate := range candidates { result = append(result, candidate.Address) } - return result[:150], nil + return result, nil } // Hook calculates reward for masternodes diff --git a/miner/worker.go b/miner/worker.go index 238f615fe8..da4f33093e 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -413,7 +413,7 @@ func (self *worker) wait() { } // Send tx sign to smart contract blockSigners. if block.NumberU64()%common.MergeSignRange == 0 || !self.config.IsTIP2019(block.Number()) { - if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block, self.chainDb); err != nil { + if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block, self.chainDb, self.coinbase); err != nil { log.Error("Fail to create tx sign for signer", "error", "err") } } diff --git a/params/version.go b/params/version.go index 2125f94074..b3f510f330 100644 --- a/params/version.go +++ b/params/version.go @@ -22,7 +22,7 @@ import ( const ( VersionMajor = 1 // Major version component of the current release - VersionMinor = 0 // Minor version component of the current release + VersionMinor = 1 // Minor version component of the current release VersionPatch = 1 // Patch version component of the current release VersionMeta = "stable" // Version metadata to append to the version string )