-
-func (c *Chain) ProcessDPoSConnectBlock(block *types.Block) error {
- mapTxFee := c.CalculateBalance(block, true)
- if err := c.DoVoting(block, mapTxFee); err != nil {
- return err
- }
- return nil
-}
-
-func (c *Chain) DoVoting(block *types.Block, mapTxFee map[bc.Hash]uint64) error {
- for _, tx := range block.Transactions {
- to := tx.Outputs[0]
- msg := &dpos.DposMsg{}
-
- if err := json.Unmarshal(tx.TxData.ReferenceData, &msg); err != nil {
- continue
- }
- var (
- address common.Address
- err error
- )
- address, err = common.NewAddressWitnessPubKeyHash(to.ControlProgram[2:], &consensus.ActiveNetParams)
- if err != nil {
- address, err = common.NewAddressWitnessScriptHash(to.ControlProgram[2:], &consensus.ActiveNetParams)
- if err != nil {
- return errors.New("ControlProgram cannot be converted to address")
- }
- }
- hash := block.Hash()
- height := block.Height
- switch msg.Type {
- case vm.OP_DELEGATE:
- continue
- case vm.OP_REGISTE:
- if mapTxFee[tx.Tx.ID] >= consensus.RegisrerForgerFee {
- data := &dpos.RegisterForgerData{}
- if err := json.Unmarshal(msg.Data, data); err != nil {
- return err
- }
- c.Engine.ProcessRegister(address.EncodeAddress(), data.Name, hash, height)
- }
- case vm.OP_VOTE:
- if mapTxFee[tx.Tx.ID] >= consensus.VoteForgerFee {
- data := &dpos.VoteForgerData{}
- if err := json.Unmarshal(msg.Data, data); err != nil {
- return err
- }
- c.Engine.ProcessVote(address.EncodeAddress(), data.Forgers, hash, height)
- }
- case vm.OP_REVOKE:
- if mapTxFee[tx.Tx.ID] >= consensus.CancelVoteForgerFee {
- data := &dpos.CancelVoteForgerData{}
- if err := json.Unmarshal(msg.Data, data); err != nil {
- return err
- }
- c.Engine.ProcessCancelVote(address.EncodeAddress(), data.Forgers, hash, height)
- }
- }
- }
- return nil
-}
-
-func (c *Chain) CalculateBalance(block *types.Block, fIsAdd bool) map[bc.Hash]uint64 {
-
- addressBalances := []engine.AddressBalance{}
- mapTxFee := make(map[bc.Hash]uint64)
- var (
- address common.Address
- err error
- )
-
- for _, tx := range block.Transactions {
- fee := uint64(0)
- for _, input := range tx.Inputs {
- if input.AssetID() != *consensus.BTMAssetID {
- continue
- }
-
- if len(tx.TxData.Inputs) == 1 &&
- (tx.TxData.Inputs[0].InputType() == types.CoinbaseInputType ||
- tx.TxData.Inputs[0].InputType() == types.ClainPeginInputType) {
- continue
- }
-
- fee += input.Amount()
- value := int64(input.Amount())
- address, err = common.NewAddressWitnessPubKeyHash(input.ControlProgram()[2:], &consensus.ActiveNetParams)
- if err != nil {
- address, err = common.NewAddressWitnessScriptHash(input.ControlProgram()[2:], &consensus.ActiveNetParams)
- if err != nil {
- continue
- }
- }
- if fIsAdd {
- value = 0 - value
- }
- addressBalances = append(addressBalances, engine.AddressBalance{address.EncodeAddress(), value})
- }
- for _, output := range tx.Outputs {
- fee -= output.Amount
- if vmutil.IsUnspendable(output.ControlProgram) {
- continue
- }
- if *output.AssetId != *consensus.BTMAssetID {
- continue
- }
- value := int64(output.Amount)
- address, err = common.NewAddressWitnessPubKeyHash(output.ControlProgram[2:], &consensus.ActiveNetParams)
- if err != nil {
- address, err = common.NewAddressWitnessScriptHash(output.ControlProgram[2:], &consensus.ActiveNetParams)
- if err != nil {
- continue
- }
- }
- if !fIsAdd {
- value = 0 - value
- }
- addressBalances = append(addressBalances, engine.AddressBalance{address.EncodeAddress(), value})
- }
- mapTxFee[tx.Tx.ID] = fee
- }
-
- c.Engine.UpdateAddressBalance(addressBalances)
- return mapTxFee
-}
-
-func (c *Chain) RepairDPoSData(oldBlockHeight uint64, oldBlockHash bc.Hash) error {
- block, err := c.GetBlockByHash(&oldBlockHash)
- if err != nil {
- return err
- }
- if block.Height != oldBlockHeight {
- return errors.New("The module vote records data with a problem")
- }
- for i := block.Height + 1; i <= c.bestNode.Height; i++ {
- b, err := c.GetBlockByHeight(i)
- if err != nil {
- return err
- }
- if err := c.ProcessDPoSConnectBlock(b); err != nil {
- return err
- }
-
- }
- return nil
-}