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 }