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  }