Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/paratime/show: Add show events command #333

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 86 additions & 14 deletions cmd/paratime/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ import (
runtimeTx "github.com/oasisprotocol/oasis-core/go/runtime/transaction"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/accounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/contracts"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/core"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/evm"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/types"

"github.com/oasisprotocol/cli/cmd/common"
Expand All @@ -35,15 +41,25 @@ const (
const (
selInvalid propertySelector = iota
selParameters
selEvents
)

var eventDecoders = []func(*types.Event) ([]client.DecodedEvent, error){
accounts.DecodeEvent,
consensusaccounts.DecodeEvent,
contracts.DecodeEvent,
core.DecodeEvent,
evm.DecodeEvent,
rofl.DecodeEvent,
}

var (
outputFormat string
selectedRound uint64

showCmd = &cobra.Command{
Use: "show { <round> [ <tx-index> | <tx-hash> ] | parameters }",
Short: "Show information about a ParaTime block, its transactions or other parameters",
Use: "show { <round> [ <tx-index> | <tx-hash> ] | parameters | events }",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commands are currently inconsistent regarding the round argument. paratime show parameters uses --round flag, while paratme show <round> uses round as a positional argument.

show events is consistent with show parameters since that was the easiest to implement. But this should probably be cleaned up (in a followup).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially it was not meant to show other things, so if we now have parameters and events, we should maybe also have show block or similar.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial idea was to resemble oasis network show. So try to autodetect what user wanted with as little typing as possible and then offer more explicit variants, if needed.

Some alternative ideas:

  • show <round> --events
  • show events:<round>
  • show <round>:events
  • or simply show all transactions with events when calling show <round>, also pass --format json and let user filter them with jq

IMO the current implementation makes the most sense.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll merge it as is for now.

Short: "Show information about a ParaTime block, its transactions, events or other parameters",
Long: "Show ParaTime-specific information about a given block round, (optionally) its transactions or other information. Use \"latest\" to use the last round.",
Aliases: []string{"s"},
Args: cobra.RangeArgs(1, 2),
Expand Down Expand Up @@ -101,13 +117,6 @@ var (
switch v := p.(type) {
case uint64:
blkNum := v
evDecoders := []client.EventDecoder{
rt.Accounts,
rt.ConsensusAccounts,
rt.Contracts,
rt.Evm,
rt.ROFL,
}

blk, err := rt.GetBlock(ctx, blkNum)
cobra.CheckErr(err)
Expand Down Expand Up @@ -151,7 +160,7 @@ var (
fmt.Println()

for evIndex, ev := range blockEvs {
prettyPrintEvent(" ", evIndex, ev, evDecoders)
prettyPrintEvent(" ", evIndex, ev)
fmt.Println()
}
}
Expand Down Expand Up @@ -249,7 +258,7 @@ var (
fmt.Println()

for evIndex, ev := range tx.Events {
prettyPrintEvent(" ", evIndex, ev, evDecoders)
prettyPrintEvent(" ", evIndex, ev)
fmt.Println()
}
} else {
Expand All @@ -261,6 +270,9 @@ var (
case selParameters:
showParameters(ctx, npa, selectedRound, rt)
return
case selEvents:
showEvents(ctx, selectedRound, rt)
return
default:
cobra.CheckErr(fmt.Errorf("selector '%s' not found", args[0]))
}
Expand Down Expand Up @@ -294,6 +306,9 @@ func selectorFromString(s string) propertySelector {
if strings.ToLower(strings.TrimSpace(s)) == "parameters" {
return selParameters
}
if strings.ToLower(strings.TrimSpace(s)) == "events" {
return selEvents
}
return selInvalid
}

Expand Down Expand Up @@ -414,14 +429,17 @@ func prettyPrintStruct(indent string, kind string, data []byte, body interface{}
fmt.Println(indent + output)
}

func prettyPrintEvent(indent string, evIndex int, ev *types.Event, decoders []client.EventDecoder) {
func prettyPrintEvent(indent string, evIndex int, ev *types.Event) {
fmt.Printf("%s--- Event %d ---\n", indent, evIndex)
fmt.Printf("%sModule: %s\n", indent, ev.Module)
fmt.Printf("%sCode: %d\n", indent, ev.Code)
if ev.TxHash != nil {
fmt.Printf("%sTx hash: %s\n", indent, ev.TxHash.String())
}
fmt.Printf("%sData:\n", indent)

for _, decoder := range decoders {
decoded, err := decoder.DecodeEvent(ev)
for _, decoder := range eventDecoders {
decoded, err := decoder(ev)
if err != nil {
continue
}
Expand All @@ -434,6 +452,37 @@ func prettyPrintEvent(indent string, evIndex int, ev *types.Event, decoders []cl
prettyPrintCBOR(indent+" ", "event", ev.Value)
}

func jsonPrintEvents(evs []*types.Event) {
out := []map[string]interface{}{}

for _, ev := range evs {
fields := make(map[string]interface{})
fields["module"] = ev.Module
fields["code"] = ev.Code
if ev.TxHash != nil {
fields["tx_hash"] = ev.TxHash.String()
}
fields["data"] = ev.Value

for _, decoder := range eventDecoders {
decoded, err := decoder(ev)
if err != nil {
continue
}
if decoded != nil {
fields["parsed"] = decoded

break
}
}
out = append(out, fields)
}

str, err := common.PrettyJSONMarshal(out)
cobra.CheckErr(err)
fmt.Printf("%s\n", str)
}

func showParameters(ctx context.Context, npa *common.NPASelection, round uint64, rt connection.RuntimeClient) {
checkErr := func(what string, err error) {
if err != nil {
Expand Down Expand Up @@ -465,6 +514,29 @@ func showParameters(ctx context.Context, npa *common.NPASelection, round uint64,
}
}

func showEvents(ctx context.Context, round uint64, rt connection.RuntimeClient) {
evs, err := rt.GetEventsRaw(ctx, round)
cobra.CheckErr(err)

if len(evs) == 0 {
if outputFormat == formatJSON {
fmt.Printf("[]\n")
} else {
fmt.Println("No events emitted in this block.")
}
return
}

if outputFormat == formatJSON {
jsonPrintEvents(evs)
} else {
for evIndex, ev := range evs {
prettyPrintEvent("", evIndex, ev)
fmt.Println()
}
}
}

func init() {
formatFlag := flag.NewFlagSet("", flag.ContinueOnError)
formatFlag.StringVar(&outputFormat, "format", formatText, "output format ["+strings.Join([]string{formatText, formatJSON}, ",")+"]")
Expand Down
14 changes: 13 additions & 1 deletion docs/paratime.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ oasis paratime add testnet sapphire2 0000000000000000000000000000000000000000000
```

```
? Description:
? Description:
? Denomination symbol: TEST
? Denomination decimal places: 18
```
Expand Down Expand Up @@ -163,6 +163,18 @@ thresholds.

By passing `--format json`, the output is formatted as JSON.

### `events` {#show-events}

This will return all Paratime events emitted in the block.

Use `--round <round>` to specify the round number.

![code shell](../examples/paratime-show/show-events.in)

![code](../examples/paratime-show/show-events.out)

By passing `--format json`, the output is formatted as JSON.

## Set information about a denomination {#denom-set}

To set information about a denomination on the specific network and paratime use
Expand Down
1 change: 1 addition & 0 deletions examples/paratime-show/show-events.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
oasis paratime show events --round 9399871 --format json
80 changes: 80 additions & 0 deletions examples/paratime-show/show-events.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[
{
"code": 1,
"data": "gaNidG9VAGIz3RCYb9ltIk8706by6j2XkXGmZGZyb21VAJZQKbOBY+XnA5YUaDhZkNc3y+nsZmFtb3VudIJHCxBZMMJwAEA=",
"module": "accounts",
"parsed": [
{
"Transfer": {
"from": "oasis1qzt9q2dns937tecrjc2xswzejrtn0jlfas40j7sz",
"to": "oasis1qp3r8hgsnphajmfzfuaa8fhjag7e0yt35cjxq0u4",
"amount": {
"Amount": "3114200000000000",
"Denomination": ""
}
},
"Burn": null,
"Mint": null
}
],
"tx_hash": "c586f05e2103adb953d2287ef22dad0532540bd02481184b5477ba8c38894e62"
},
{
"code": 1,
"data": "gqNidG9VAIyCi8jiQIOmvod+yJYxN0GhktyEZGZyb21VACg9qHdJLY0x3unzFR/SHF3dLD+oZmFtb3VudIJIAWNFeMTiZV9Ao2J0b1UAYjPdEJhv2W0iTzvTpvLqPZeRcaZkZnJvbVUAKD2od0ktjTHe6fMVH9IcXd0sP6hmYW1vdW50gkcH3eTk7RgAQA==",
"module": "accounts",
"parsed": [
{
"Transfer": {
"from": "oasis1qq5rm2rhfykc6vw7a8e3287jr3wa6tpl4qv49gzh",
"to": "oasis1qzxg9z7gufqg8f47salv3933xaq6rykusslsq4k7",
"amount": {
"Amount": "100000001733846367",
"Denomination": ""
}
},
"Burn": null,
"Mint": null
},
{
"Transfer": {
"from": "oasis1qq5rm2rhfykc6vw7a8e3287jr3wa6tpl4qv49gzh",
"to": "oasis1qp3r8hgsnphajmfzfuaa8fhjag7e0yt35cjxq0u4",
"amount": {
"Amount": "2214300000000000",
"Denomination": ""
}
},
"Burn": null,
"Mint": null
}
],
"tx_hash": "de7e52e94f4614ec0b0de47971abc12d5070278e9401c2466ec5664a71bdc57d"
},
{
"code": 1,
"data": "gaFmYW1vdW50GXmm",
"module": "core",
"parsed": [
{
"GasUsed": {
"amount": 31142
}
}
],
"tx_hash": "c586f05e2103adb953d2287ef22dad0532540bd02481184b5477ba8c38894e62"
},
{
"code": 1,
"data": "gaFmYW1vdW50GVZ/",
"module": "core",
"parsed": [
{
"GasUsed": {
"amount": 22143
}
}
],
"tx_hash": "de7e52e94f4614ec0b0de47971abc12d5070278e9401c2466ec5664a71bdc57d"
}
]
Loading