github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/deploy/util/chains_info.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/hyperledger/burrow/deploy/def" 9 "github.com/hyperledger/burrow/logging" 10 11 "encoding/json" 12 13 "github.com/elgs/gojq" 14 "github.com/hyperledger/burrow/acm/validator" 15 ) 16 17 func GetBlockHeight(client *def.Client, logger *logging.Logger) (latestBlockHeight uint64, err error) { 18 stat, err := client.Status(logger) 19 if err != nil { 20 return 0, err 21 } 22 return stat.SyncInfo.LatestBlockHeight, nil 23 } 24 25 func AccountsInfo(account, field string, client *def.Client, logger *logging.Logger) (string, error) { 26 address, err := client.ParseAddress(account, logger) 27 if err != nil { 28 return "", err 29 } 30 acc, err := client.GetAccount(address) 31 if err != nil { 32 return "", err 33 } 34 if acc == nil { 35 return "", fmt.Errorf("Account %s does not exist", account) 36 } 37 38 bs, err := json.Marshal(acc) 39 if err != nil { 40 return "", err 41 } 42 jq, err := gojq.NewStringQuery(string(bs)) 43 if err == nil { 44 logger.InfoMsg("Attempting jq query") 45 res, err := jq.Query(field) 46 if err == nil { 47 return fmt.Sprintf("%v", res), nil 48 } else { 49 logger.TraceMsg("Got error from jq query: %v trying legacy query (probably fine)...", "error", fmt.Sprintf("%v", err)) 50 } 51 } 52 53 var s string 54 if strings.Contains(field, "permissions") { 55 fields := strings.Split(field, ".") 56 57 if len(fields) > 1 { 58 switch fields[1] { 59 case "roles": 60 s = strings.Join(acc.Permissions.Roles, ",") 61 case "base", "perms": 62 s = strconv.Itoa(int(acc.Permissions.Base.Perms)) 63 case "set": 64 s = strconv.Itoa(int(acc.Permissions.Base.SetBit)) 65 } 66 } 67 } else if field == "balance" { 68 s = itoaU64(acc.Balance) 69 } 70 71 if err != nil { 72 return "", err 73 } 74 75 return s, nil 76 } 77 78 func NamesInfo(name, field string, client *def.Client, logger *logging.Logger) (string, error) { 79 entry, err := client.GetName(name, logger) 80 if err != nil { 81 return "", err 82 } 83 84 switch strings.ToLower(field) { 85 case "name": 86 return name, nil 87 case "owner": 88 return entry.Owner.String(), nil 89 case "data": 90 return entry.Data, nil 91 case "expires": 92 return itoaU64(entry.Expires), nil 93 default: 94 return "", fmt.Errorf("Field %s not recognized", field) 95 } 96 } 97 98 func ValidatorsInfo(query string, client *def.Client, logger *logging.Logger) (interface{}, error) { 99 // Currently there is no notion of 'unbonding validators' we can revisit what should go here or whether this deserves 100 // to exist as a job 101 validatorSet, err := client.GetValidatorSet(logger) 102 if err != nil { 103 return nil, err 104 } 105 // Yes, this feels a bit silly, but it is the easiest way to get the generic map of slice object that gojq needs 106 // mapstructure is not able to do this it would seem. 107 bs, err := json.Marshal(map[string]interface{}{ 108 "Height": validatorSet.Height, 109 "Set": validatorMap(validatorSet.Set), 110 }) 111 if err != nil { 112 return nil, err 113 } 114 jq, err := gojq.NewStringQuery(string(bs)) 115 if err != nil { 116 return nil, err 117 } 118 return jq.Query(query) 119 } 120 121 func validatorMap(vs []*validator.Validator) map[string]interface{} { 122 set := validator.UnpersistSet(vs) 123 vsMap := make(map[string]interface{}, len(vs)) 124 vsMap["TotalPower"] = set.TotalPower().String() 125 vsMap["String"] = set.String() 126 for _, v := range vs { 127 vsMap[v.GetPublicKey().GetAddress().String()] = v 128 } 129 return vsMap 130 } 131 132 func itoaU64(i uint64) string { 133 return strconv.FormatUint(i, 10) 134 }