Skip to content

Commit

Permalink
Merge pull request #4609 from oasisprotocol/tjanez/stake-account-info…
Browse files Browse the repository at this point in the history
…-historical-22.0.x

[BACKPORT/22.0.x] go/oasis-node/cmd/stake: Allow querying historical account info
  • Loading branch information
tjanez authored Mar 28, 2022
2 parents 34f6000 + 78adf4d commit 3bb134f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
4 changes: 4 additions & 0 deletions .changelog/4416.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
go/oasis-node/cmd/stake: Allow querying historical account info

The `oasis-node stake account info` CLI command now accepts `--height` flag
which allows one to query an account's info at an arbitrary height.
30 changes: 22 additions & 8 deletions go/oasis-node/cmd/stake/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/spf13/viper"

"github.com/oasisprotocol/oasis-core/go/common/prettyprint"
consensus "github.com/oasisprotocol/oasis-core/go/consensus/api"
cmdCommon "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common"
cmdConsensus "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/consensus"
cmdContext "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/context"
Expand All @@ -20,6 +21,9 @@ import (
)

const (
// CfgHeight configures the consensus height.
CfgHeight = "height"

// CfgAccountAddr configures the account address.
CfgAccountAddr = "stake.account.address"

Expand Down Expand Up @@ -57,6 +61,7 @@ var (
sharesFlags = flag.NewFlagSet("", flag.ContinueOnError)
commonEscrowFlags = flag.NewFlagSet("", flag.ContinueOnError)
commissionScheduleFlags = flag.NewFlagSet("", flag.ContinueOnError)
accountInfoFlags = flag.NewFlagSet("", flag.ContinueOnError)
accountTransferFlags = flag.NewFlagSet("", flag.ContinueOnError)
accountBurnFlags = flag.NewFlagSet("", flag.ContinueOnError)
accountAllowFlags = flag.NewFlagSet("", flag.ContinueOnError)
Expand Down Expand Up @@ -144,17 +149,20 @@ func doAccountInfo(cmd *cobra.Command, args []string) {
conn, client := doConnect(cmd)
defer conn.Close()

height := viper.GetInt64(CfgHeight)

ctx := context.Background()
acct := getAccount(ctx, cmd, addr, client)
outgoingDelegationInfos := getDelegationInfosFor(ctx, cmd, addr, client)
incomingDelegations := getDelegationsTo(ctx, cmd, addr, client)
outgoingDebondingDelegationInfos := getDebondingDelegationInfosFor(ctx, cmd, addr, client)
incomingDebondingDelegations := getDebondingDelegationsTo(ctx, cmd, addr, client)
symbol := getTokenSymbol(ctx, cmd, client)
exp := getTokenValueExponent(ctx, cmd, client)
acct := getAccount(ctx, addr, height, client)
outgoingDelegationInfos := getDelegationInfosFor(ctx, addr, height, client)
incomingDelegations := getDelegationsTo(ctx, addr, height, client)
outgoingDebondingDelegationInfos := getDebondingDelegationInfosFor(ctx, addr, height, client)
incomingDebondingDelegations := getDebondingDelegationsTo(ctx, addr, height, client)
symbol := getTokenSymbol(ctx, client)
exp := getTokenValueExponent(ctx, client)
ctx = context.WithValue(ctx, prettyprint.ContextKeyTokenSymbol, symbol)
ctx = context.WithValue(ctx, prettyprint.ContextKeyTokenValueExponent, exp)

fmt.Printf("Account State for Height: %d\n", height)
fmt.Println("Balance:")
prettyPrintAccountBalanceAndDelegationsFrom(ctx, addr, acct.General, outgoingDelegationInfos, outgoingDebondingDelegationInfos, " ", os.Stdout)
fmt.Println()
Expand Down Expand Up @@ -210,8 +218,10 @@ func doAccountNonce(cmd *cobra.Command, args []string) {
conn, client := doConnect(cmd)
defer conn.Close()

height := consensus.HeightLatest

ctx := context.Background()
acct := getAccount(ctx, cmd, addr, client)
acct := getAccount(ctx, addr, height, client)
fmt.Println(acct.General.Nonce)
}

Expand Down Expand Up @@ -504,6 +514,7 @@ func registerAccountCmd() {
}

accountInfoCmd.Flags().AddFlagSet(commonAccountFlags)
accountInfoCmd.Flags().AddFlagSet(accountInfoFlags)
accountNonceCmd.Flags().AddFlagSet(commonAccountFlags)
accountValidateAddressCmd.Flags().AddFlagSet(commonAccountFlags)
accountValidateAddressCmd.Flags().AddFlagSet(cmdFlags.VerboseFlags)
Expand All @@ -529,6 +540,9 @@ func init() {
sharesFlags.String(CfgShares, "0", "amount of shares for the transaction")
_ = viper.BindPFlags(sharesFlags)

accountInfoFlags.Int64(CfgHeight, consensus.HeightLatest, "height at which to query for info (default to latest height)")
_ = viper.BindPFlags(accountInfoFlags)

accountTransferFlags.String(CfgTransferDestination, "", "transfer destination account address")
_ = viper.BindPFlags(accountTransferFlags)
accountTransferFlags.AddFlagSet(cmdConsensus.TxFlags)
Expand Down
49 changes: 25 additions & 24 deletions go/oasis-node/cmd/stake/stake.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func doConnect(cmd *cobra.Command) (*grpc.ClientConn, api.Backend) {
return conn, client
}

func getTokenSymbol(ctx context.Context, cmd *cobra.Command, client api.Backend) string {
func getTokenSymbol(ctx context.Context, client api.Backend) string {
symbol, err := client.TokenSymbol(ctx)
if err != nil {
logger.Error("failed to query token's symbol",
Expand All @@ -81,7 +81,7 @@ func getTokenSymbol(ctx context.Context, cmd *cobra.Command, client api.Backend)
return symbol
}

func getTokenValueExponent(ctx context.Context, cmd *cobra.Command, client api.Backend) uint8 {
func getTokenValueExponent(ctx context.Context, client api.Backend) uint8 {
exp, err := client.TokenValueExponent(ctx)
if err != nil {
logger.Error("failed to query token's value exponent",
Expand All @@ -92,8 +92,8 @@ func getTokenValueExponent(ctx context.Context, cmd *cobra.Command, client api.B
return exp
}

func getAccount(ctx context.Context, cmd *cobra.Command, addr api.Address, client api.Backend) *api.Account {
acct, err := client.Account(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest})
func getAccount(ctx context.Context, addr api.Address, height int64, client api.Backend) *api.Account {
acct, err := client.Account(ctx, &api.OwnerQuery{Owner: addr, Height: height})
if err != nil {
logger.Error("failed to query account",
"address", addr,
Expand All @@ -106,11 +106,11 @@ func getAccount(ctx context.Context, cmd *cobra.Command, addr api.Address, clien

func getDelegationInfosFor(
ctx context.Context,
cmd *cobra.Command,
addr api.Address,
height int64,
client api.Backend,
) map[api.Address]*api.DelegationInfo {
delInfos, err := client.DelegationInfosFor(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest})
delInfos, err := client.DelegationInfosFor(ctx, &api.OwnerQuery{Owner: addr, Height: height})
if err != nil {
logger.Error("failed to query (outgoing) delegation infos for account",
"address", addr,
Expand All @@ -123,11 +123,11 @@ func getDelegationInfosFor(

func getDelegationsTo(
ctx context.Context,
cmd *cobra.Command,
addr api.Address,
height int64,
client api.Backend,
) map[api.Address]*api.Delegation {
delegations, err := client.DelegationsTo(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest})
delegations, err := client.DelegationsTo(ctx, &api.OwnerQuery{Owner: addr, Height: height})
if err != nil {
logger.Error("failed to query (incoming) delegations to account",
"address", addr,
Expand All @@ -140,11 +140,11 @@ func getDelegationsTo(

func getDebondingDelegationInfosFor(
ctx context.Context,
cmd *cobra.Command,
addr api.Address,
height int64,
client api.Backend,
) map[api.Address][]*api.DebondingDelegationInfo {
delInfoLists, err := client.DebondingDelegationInfosFor(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest})
delInfoLists, err := client.DebondingDelegationInfosFor(ctx, &api.OwnerQuery{Owner: addr, Height: height})
if err != nil {
logger.Error("failed to query (outgoing) debonding delegation infos for account",
"address", addr,
Expand All @@ -157,11 +157,11 @@ func getDebondingDelegationInfosFor(

func getDebondingDelegationsTo(
ctx context.Context,
cmd *cobra.Command,
addr api.Address,
height int64,
client api.Backend,
) map[api.Address][]*api.DebondingDelegation {
delegations, err := client.DebondingDelegationsTo(ctx, &api.OwnerQuery{Owner: addr, Height: consensus.HeightLatest})
delegations, err := client.DebondingDelegationsTo(ctx, &api.OwnerQuery{Owner: addr, Height: height})
if err != nil {
logger.Error("failed to query (incoming) debonding delegations to account",
"address", addr,
Expand All @@ -180,18 +180,17 @@ func doInfo(cmd *cobra.Command, args []string) {
conn, client := doConnect(cmd)
defer conn.Close()

ctx := context.Background()
height := consensus.HeightLatest

symbol := getTokenSymbol(ctx, cmd, client)
ctx := context.Background()
symbol := getTokenSymbol(ctx, client)
fmt.Printf("Token's ticker symbol: %s\n", symbol)

exp := getTokenValueExponent(ctx, cmd, client)
exp := getTokenValueExponent(ctx, client)
fmt.Printf("Token's value base-10 exponent: %d\n", exp)

ctx = context.WithValue(ctx, prettyprint.ContextKeyTokenSymbol, symbol)
ctx = context.WithValue(ctx, prettyprint.ContextKeyTokenValueExponent, exp)

totalSupply, err := client.TotalSupply(ctx, consensus.HeightLatest)
totalSupply, err := client.TotalSupply(ctx, height)
if err != nil {
logger.Error("failed to query total supply",
"err", err,
Expand All @@ -202,7 +201,7 @@ func doInfo(cmd *cobra.Command, args []string) {
token.PrettyPrintAmount(ctx, *totalSupply, os.Stdout)
fmt.Println()

commonPool, err := client.CommonPool(ctx, consensus.HeightLatest)
commonPool, err := client.CommonPool(ctx, height)
if err != nil {
logger.Error("failed to query common pool",
"err", err,
Expand All @@ -213,7 +212,7 @@ func doInfo(cmd *cobra.Command, args []string) {
token.PrettyPrintAmount(ctx, *commonPool, os.Stdout)
fmt.Println()

lastBlockFees, err := client.LastBlockFees(ctx, consensus.HeightLatest)
lastBlockFees, err := client.LastBlockFees(ctx, height)
if err != nil {
logger.Error("failed to query last block fees",
"err", err,
Expand All @@ -224,7 +223,7 @@ func doInfo(cmd *cobra.Command, args []string) {
token.PrettyPrintAmount(ctx, *lastBlockFees, os.Stdout)
fmt.Println()

governanceDeposits, err := client.GovernanceDeposits(ctx, consensus.HeightLatest)
governanceDeposits, err := client.GovernanceDeposits(ctx, height)
if err != nil {
logger.Error("failed to query governance deposits",
"err", err,
Expand All @@ -244,7 +243,7 @@ func doInfo(cmd *cobra.Command, args []string) {
api.KindRuntimeKeyManager,
}
for _, kind := range thresholdsToQuery {
thres, err := client.Threshold(ctx, &api.ThresholdQuery{Kind: kind, Height: consensus.HeightLatest})
thres, err := client.Threshold(ctx, &api.ThresholdQuery{Kind: kind, Height: height})
if err != nil {
if errors.Is(err, api.ErrInvalidThreshold) {
logger.Warn(fmt.Sprintf("invalid staking threshold kind: %s", kind))
Expand All @@ -269,9 +268,11 @@ func doList(cmd *cobra.Command, args []string) {
conn, client := doConnect(cmd)
defer conn.Close()

height := consensus.HeightLatest

ctx := context.Background()

addresses, err := client.Addresses(ctx, consensus.HeightLatest)
addresses, err := client.Addresses(ctx, height)
if err != nil {
logger.Error("failed to query addresses",
"err", err,
Expand All @@ -286,7 +287,7 @@ func doList(cmd *cobra.Command, args []string) {
// NOTE: getAccount()'s output doesn't contain an account's address,
// so we need to add it manually.
acctWithAddr := make(map[api.Address]*api.Account)
acctWithAddr[addr] = getAccount(ctx, cmd, addr, client)
acctWithAddr[addr] = getAccount(ctx, addr, height, client)
prettyAcct, err := cmdCommon.PrettyJSONMarshal(acctWithAddr)
if err != nil {
logger.Error("failed to get pretty JSON of account",
Expand Down

0 comments on commit 3bb134f

Please sign in to comment.