From 0e7c8c1eb8be1a3e33167736fefdcb354b0f2215 Mon Sep 17 00:00:00 2001 From: Nguyen Ba Tam Date: Mon, 14 Jan 2019 12:00:19 +0700 Subject: [PATCH] reduce number sign transaction --- common/constants.go | 4 +++ contracts/utils.go | 56 ++++++++++++++++++++++-------------------- eth/backend.go | 46 ++++++++++++++++++---------------- internal/ethapi/api.go | 31 +++++++++++++++-------- miner/worker.go | 6 +++-- params/config.go | 3 +++ 6 files changed, 87 insertions(+), 59 deletions(-) diff --git a/common/constants.go b/common/constants.go index 1cad593c9e..715ad4f0c6 100644 --- a/common/constants.go +++ b/common/constants.go @@ -1,5 +1,7 @@ package common +import "math/big" + const ( RewardMasterPercent = 40 RewardVoterPercent = 50 @@ -15,7 +17,9 @@ const ( BlocksPerYear = uint64(15768000) LimitThresholdNonceInQueue = 10 MinGasPrice = 2500 + MergeSignRange = 15 ) +var TIP2019Block = big.NewInt(1050000) var IsTestnet bool = false var StoreRewardFolder string diff --git a/contracts/utils.go b/contracts/utils.go index 08472c121e..15be3165d2 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -31,19 +31,19 @@ import ( "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/posv" + "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" + randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" - randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract" ) const ( @@ -321,7 +321,6 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, number ui data := make(map[common.Hash][]common.Address) for i := startBlockNumber; i <= prevCheckpoint+(rCheckpoint*2)-1; i++ { header := chain.GetHeaderByNumber(i) - if signData, ok := c.BlockSigners.Get(header.Hash()); ok { txs := signData.([]*types.Transaction) for _, tx := range txs { @@ -362,30 +361,32 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, number ui } for i := startBlockNumber; i <= endBlockNumber; i++ { - block := chain.GetHeaderByNumber(i) - addrs := data[block.Hash()] - // Filter duplicate address. - if len(addrs) > 0 { - addrSigners := make(map[common.Address]bool) - for _, masternode := range masternodes { - for _, addr := range addrs { - if addr == masternode { - if _, ok := addrSigners[addr]; !ok { - addrSigners[addr] = true + if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) { + block := chain.GetHeaderByNumber(i) + addrs := data[block.Hash()] + // Filter duplicate address. + if len(addrs) > 0 { + addrSigners := make(map[common.Address]bool) + for _, masternode := range masternodes { + for _, addr := range addrs { + if addr == masternode { + if _, ok := addrSigners[addr]; !ok { + addrSigners[addr] = true + } + break } - break } } - } - for addr := range addrSigners { - _, exist := signers[addr] - if exist { - signers[addr].Sign++ - } else { - signers[addr] = &rewardLog{1, new(big.Int)} + for addr := range addrSigners { + _, exist := signers[addr] + if exist { + signers[addr].Sign++ + } else { + signers[addr] = &rewardLog{1, new(big.Int)} + } + *totalSigner++ } - *totalSigner++ } } } @@ -427,15 +428,15 @@ func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) return owner } -func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) { - rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward) +func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) { + rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber) if err != nil { return err, nil } return nil, rewards } -func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int) (map[common.Address]*big.Int, error) { +func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) { owner := GetCandidatesOwnerBySigner(state, masterAddr) balances := make(map[common.Address]*big.Int) rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent)) @@ -451,6 +452,9 @@ func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.Sta // Get voters capacities. voterCaps := make(map[common.Address]*big.Int) for _, voteAddr := range voters { + if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber { + continue + } voterCap := GetVoterCap(state, masterAddr, voteAddr) totalCap.Add(totalCap, voterCap) voterCaps[voteAddr] = voterCap diff --git a/eth/backend.go b/eth/backend.go index d8eba90f7b..cdd9788b71 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/contracts" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/state" //"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -52,7 +53,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/core/state" ) type LesServer interface { @@ -197,8 +197,10 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { // silently return as this node doesn't have masternode permission to sign block return nil } - if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil { - return fmt.Errorf("Fail to create tx sign for importing block: %v", err) + if block.NumberU64()%common.MergeSignRange == 0 || !eth.chainConfig.IsTIP2019(block.Number()) { + if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil { + return fmt.Errorf("Fail to create tx sign for importing block: %v", err) + } } return nil } @@ -256,27 +258,29 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if len(penSigners) > 0 { // Loop for each block to check missing sign. for i := prevEpoc; i < blockNumberEpoc; i++ { - bheader := chain.GetHeaderByNumber(i) - bhash := bheader.Hash() - block := chain.GetBlock(bhash, i) - if len(penSigners) > 0 { - signedMasternodes, err := contracts.GetSignersFromContract(canonicalState, block) - if err != nil { - return nil, err - } - if len(signedMasternodes) > 0 { - // Check signer signed? - for _, signed := range signedMasternodes { - for j, addr := range penSigners { - if signed == addr { - // Remove it from dupSigners. - penSigners = append(penSigners[:j], penSigners[j+1:]...) + if i%common.MergeSignRange == 0 || !chainConfig.IsTIP2019(big.NewInt(int64(i))) { + bheader := chain.GetHeaderByNumber(i) + bhash := bheader.Hash() + block := chain.GetBlock(bhash, i) + if len(penSigners) > 0 { + signedMasternodes, err := contracts.GetSignersFromContract(canonicalState, block) + if err != nil { + return nil, err + } + if len(signedMasternodes) > 0 { + // Check signer signed? + for _, signed := range signedMasternodes { + for j, addr := range penSigners { + if signed == addr { + // Remove it from dupSigners. + penSigners = append(penSigners[:j], penSigners[j+1:]...) + } } } } + } else { + break } - } else { - break } } } @@ -323,7 +327,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { voterResults := make(map[common.Address]interface{}) if len(signers) > 0 { for signer, calcReward := range rewardSigners { - err, rewards := contracts.CalculateRewardForHolders(foundationWalletAddr, canonicalState, signer, calcReward) + err, rewards := contracts.CalculateRewardForHolders(foundationWalletAddr, canonicalState, signer, calcReward, number) if err != nil { log.Crit("Fail to calculate reward for holders.", "error", err) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index eae67ab31c..d9bdbc000a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -865,18 +865,29 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx var filterSigners []common.Address finality := int32(0) if b.Number().Int64() > 0 { - engine := s.b.GetEngine() - addrBlockSigner := common.HexToAddress(common.BlockSigners) - signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, b.Hash()) - if err != nil { - log.Error("Fail to get signers from block signer SC.", "error", err) + curBlockNumber := b.Number().Uint64() + prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange)) + latestBlockNumber := s.b.CurrentBlock().Number().Uint64() + if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) { + prevBlockNumber = curBlockNumber } - // Get block epoc latest. - if s.b.ChainConfig().Posv != nil { - lastCheckpointNumber := rpc.BlockNumber(b.Number().Uint64() - (b.Number().Uint64() % s.b.ChainConfig().Posv.Epoch)) - prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, lastCheckpointNumber) + if engine, ok := s.b.GetEngine().(*posv.Posv); ok { + prevBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(prevBlockNumber)) + addrBlockSigner := common.HexToAddress(common.BlockSigners) + signers, err = contracts.GetSignersByExecutingEVM(addrBlockSigner, client, prevBlock.Hash()) + if err != nil { + log.Error("Fail to get signers from block signer SC.", "error", err) + return nil, err + } + validator, _ := engine.RecoverValidator(b.Header()) + creator, _ := engine.RecoverSigner(b.Header()) + signers = append(signers, validator) + signers = append(signers, creator) + // Get block epoc latest. + lastCheckpointNumber := prevBlockNumber - (prevBlockNumber % s.b.ChainConfig().Posv.Epoch) + prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber)) if prevCheckpointBlock != nil { - masternodes := engine.(*posv.Posv).GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), b.Number().Uint64(), s.b.ChainConfig().Posv.Epoch) + masternodes := engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), curBlockNumber, s.b.ChainConfig().Posv.Epoch) countFinality := 0 for _, masternode := range masternodes { for _, signer := range signers { diff --git a/miner/worker.go b/miner/worker.go index d71b39fe7b..25af63faa5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -410,8 +410,10 @@ func (self *worker) wait() { } } // Send tx sign to smart contract blockSigners. - if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block, self.chainDb); err != nil { - log.Error("Fail to create tx sign for signer", "error", "err") + 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 { + log.Error("Fail to create tx sign for signer", "error", "err") + } } } } diff --git a/params/config.go b/params/config.go index a219baffa9..bffd3da55d 100644 --- a/params/config.go +++ b/params/config.go @@ -213,6 +213,9 @@ func (c *ChainConfig) IsConstantinople(num *big.Int) bool { return isForked(c.ConstantinopleBlock, num) } +func (c *ChainConfig) IsTIP2019(num *big.Int) bool { + return isForked(common.TIP2019Block, num) +} // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice). // // The returned GasTable's fields shouldn't, under any circumstances, be changed.