github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/consensus/vdpos/api.go (about)

     1  // Copyright 2019 The inb-go Authors
     2  // This file is part of the inb-go library.
     3  //
     4  // The inb-go library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The inb-go library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the inb-go library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package vdpos implements the delegated-proof-of-stake consensus engine.
    18  package vdpos
    19  
    20  import (
    21  	"fmt"
    22  	"github.com/insight-chain/inb-go/common"
    23  	"github.com/insight-chain/inb-go/consensus"
    24  	"github.com/insight-chain/inb-go/core/types"
    25  	"github.com/insight-chain/inb-go/log"
    26  	"github.com/insight-chain/inb-go/rlp"
    27  	"github.com/insight-chain/inb-go/trie"
    28  )
    29  
    30  // API is a user facing RPC API to allow controlling the signer and voting
    31  // mechanisms of the delegated-proof-of-stake scheme.
    32  type API struct {
    33  	chain consensus.ChainReader
    34  	vdpos *Vdpos
    35  }
    36  
    37  func (api *API) GetSigners(number uint64) ([]common.Address, error) {
    38  	header := api.chain.GetHeaderByNumber(number)
    39  	if header == nil {
    40  		return nil, errUnknownBlock
    41  	}
    42  	return api.vdpos.getSigners(header)
    43  }
    44  
    45  func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
    46  	header := api.chain.GetHeaderByHash(hash)
    47  	if header == nil {
    48  		return nil, errUnknownBlock
    49  	}
    50  	return api.vdpos.getSigners(header)
    51  }
    52  
    53  func (api *API) GetCandidateNodesInfo() []*types.Tally {
    54  	tallySlice := []*types.Tally{}
    55  	var err error
    56  	header := api.chain.CurrentHeader()
    57  
    58  	//b := header.Extra[32 : len(header.Extra)-65]
    59  	//headerExtra := HeaderExtra{}
    60  	//val := &headerExtra
    61  	//err = rlp.DecodeBytes(b, val)
    62  
    63  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
    64  
    65  	if err != nil {
    66  		return nil
    67  	}
    68  
    69  	tallyTrie := vdposContext.TallyTrie()
    70  
    71  	tallyIterator := trie.NewIterator(tallyTrie.PrefixIterator(nil))
    72  
    73  	existTally := tallyIterator.Next()
    74  	if !existTally {
    75  		return nil
    76  	}
    77  	for existTally {
    78  		tallyRLP := tallyIterator.Value
    79  		tally := new(types.Tally)
    80  		if err := rlp.DecodeBytes(tallyRLP, tally); err != nil {
    81  			log.Error("Failed to decode tally")
    82  			return nil
    83  		}
    84  
    85  		tallySlice = append(tallySlice, tally)
    86  		existTally = tallyIterator.Next()
    87  	}
    88  	return tallySlice
    89  
    90  }
    91  
    92  func (api *API) GetSuperNodesInfo() []*types.Tally {
    93  	var err error
    94  	header := api.chain.CurrentHeader()
    95  
    96  	b := header.Extra[32 : len(header.Extra)-65]
    97  	headerExtra := HeaderExtra{}
    98  	val := &headerExtra
    99  	err = rlp.DecodeBytes(b, val)
   100  	if err != nil {
   101  		return nil
   102  	}
   103  
   104  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
   105  	if err != nil {
   106  		return nil
   107  	}
   108  
   109  	tallyTrie := vdposContext.TallyTrie()
   110  
   111  	//signersPool, err := vdposContext.GetSignersFromTrie()
   112  	//if err != nil {
   113  	//	return nil
   114  	//}
   115  
   116  	nodesInfo := []*types.Tally{}
   117  	for _, addr := range val.SignersPool {
   118  		//for _, addr := range signersPool {
   119  		tallyRLP := tallyTrie.Get(addr[:])
   120  		tally := new(types.Tally)
   121  		if tallyRLP != nil {
   122  			if err := rlp.DecodeBytes(tallyRLP, tally); err != nil {
   123  				fmt.Println(err)
   124  				continue
   125  			}
   126  		}
   127  		nodesInfo = append(nodesInfo, tally)
   128  	}
   129  	return nodesInfo
   130  }
   131  
   132  func (api *API) GetLightTokenByAddress(address common.Address) *types.LightToken {
   133  	header := api.chain.CurrentHeader()
   134  	if header == nil {
   135  		return nil
   136  	}
   137  
   138  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
   139  	if err != nil {
   140  		return nil
   141  	}
   142  
   143  	lightToken, err := vdposContext.GetLightToken(address)
   144  	if err != nil {
   145  		return nil
   146  	} else {
   147  		return lightToken
   148  	}
   149  }
   150  
   151  func (api *API) GetLightTokenAccountByAccountAddress(address common.Address) *types.LightTokenAccount {
   152  	header := api.chain.CurrentHeader()
   153  	if header == nil {
   154  		return nil
   155  	}
   156  
   157  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
   158  	if err != nil {
   159  		return nil
   160  	}
   161  
   162  	lightTokenAccount, _ := vdposContext.GetLightTokenAccountByAddress(address)
   163  	return lightTokenAccount
   164  }
   165  
   166  func (api *API) GetLightTokenBalanceByAddress(accountAddress common.Address, lightTokenAddress common.Address) string {
   167  	header := api.chain.CurrentHeader()
   168  	if header == nil {
   169  		return ""
   170  	}
   171  
   172  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
   173  	if err != nil {
   174  		return ""
   175  	}
   176  
   177  	balance, _ := vdposContext.GetLightTokenBalanceByAddress(accountAddress, lightTokenAddress)
   178  	return balance.String()
   179  }
   180  
   181  func (api *API) GetLightTokenStakingsByAddress(accountAddress common.Address, lightTokenAddress common.Address) []*types.Staking {
   182  	header := api.chain.CurrentHeader()
   183  	if header == nil {
   184  		return nil
   185  	}
   186  
   187  	vdposContext, err := types.NewVdposContextFromProto(api.vdpos.db, header.VdposContext)
   188  	if err != nil {
   189  		return nil
   190  	}
   191  
   192  	stakings, err := vdposContext.GetLightTokenStakingsByAddress(accountAddress, lightTokenAddress)
   193  	if err != nil {
   194  		return nil
   195  	}
   196  	return stakings
   197  }