Skip to content

Commit

Permalink
[cli] Fix issues with showing the output for a transaction (#16190) (#…
Browse files Browse the repository at this point in the history
…16193)

## Description 

This fixes the panic that tabled throws when trying to show the output
for a transaction that has no inputs or commands. (e.g., calling `client
call --package 0x2 --module kiosk --function default`).

## Test Plan 

Existing tests, manual test.

Before:
```
thread 'main' panicked at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tabled-0.15.0/src/grid/records/records_mut.rs:25:18:
index out of bounds: the len is 0 but the index is 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2024-02-11T03:33:37.781716Z ERROR telemetry_subscribers: panicked at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tabled-0.15.0/src/grid/records/records_mut.rs:25:18:
index out of bounds: the len is 0 but the index is 0 panic.file="/Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tabled-0.15.0/src/grid/records/records_mut.rs" panic.line=25 panic.column=18
```

After:
```
Transaction Digest: ANmDQptNpb72oGKgb4Wygq9uFDWLxJwPAo865e75kP8N
╭─────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Data                                                                            │
├─────────────────────────────────────────────────────────────────────────────────────────────┤
│ Sender: 0x0fe375fff0ee40d20c54a7f2478b9b5c7eaa3625b7611f9661ec5faefb4a6fea                  │
│ Gas Owner: 0x0fe375fff0ee40d20c54a7f2478b9b5c7eaa3625b7611f9661ec5faefb4a6fea               │
│ Gas Budget: 1000000000 MIST                                                                 │
│ Gas Price: 1000 MIST                                                                        │
│ Gas Payment:                                                                                │
│  ┌──                                                                                        │
│  │ ID: 0x1270f13fabe5a1622179827643e8d0989a689a2dfb2e0ff74e97685186159c73                   │
│  │ Version: 17                                                                              │
│  │ Digest: 2DTL2j9YGvy92AUhd5ECzx3jGLCk98VA4muvWqu4A4xs                                     │
│  └──                                                                                        │
│                                                                                             │
│ Transaction Kind: Programmable                                                              │
│   No input objects for this transaction                                                     │
│ ╭──────────────────────────────────────────────────────────────────────────────────╮        │
│ │ Commands                                                                         │        │
│ ├──────────────────────────────────────────────────────────────────────────────────┤        │
│ │ 0  MoveCall:                                                                     │        │
│ │  ┌                                                                               │        │
│ │  │ Function:  default                                                            │        │
│ │  │ Module:    kiosk                                                              │        │
│ │  │ Package:   0x0000000000000000000000000000000000000000000000000000000000000002 │        │
│ │  └                                                                               │        │
│ ╰──────────────────────────────────────────────────────────────────────────────────╯        │
│                                                                                             │
│ Signatures:                                                                                 │
│    +OOZ8uwjS+XK3sz0TyMf19d6ouwLSfqiF57jSFxkH0KNJN2c9tDebN3JrqEHXV6wzON492THldd95oLDW+6UBA== │
│                                                                                             │
╰─────────────────────────────────────────────────────────────────────────────────────────────╯
```
---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [x] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
Fixed the CLI to handle the table output for a transaction that has no
inputs or commands. (e.g., calling `client call --package 0x2 --module
kiosk --function default`).
  • Loading branch information
stefan-mysten committed Feb 12, 2024
1 parent 8d80cf5 commit 266bdf4
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 90 deletions.
108 changes: 61 additions & 47 deletions crates/sui-json-rpc-types/src/displays/transaction_displays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,75 @@ use tabled::{

impl<'a> Display for Pretty<'a, SuiProgrammableTransactionBlock> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut builder = TableBuilder::default();

let Pretty(ptb) = self;
let SuiProgrammableTransactionBlock { inputs, commands } = ptb;

for (i, input) in inputs.iter().enumerate() {
match input {
SuiCallArg::Pure(v) => {
let pure_arg = if let Some(t) = v.value_type() {
format!(
"{i:<3} Pure Arg: Type: {}, Value: {}",
t,
v.value().to_json_value()
)
} else {
format!("{i:<3} Pure Arg: {}", v.value().to_json_value())
};
builder.push_record(vec![pure_arg]);
}
SuiCallArg::Object(SuiObjectArg::ImmOrOwnedObject { object_id, .. }) => {
builder.push_record(vec![format!("{i:<3} Imm/Owned Object ID: {}", object_id)]);
}
SuiCallArg::Object(SuiObjectArg::SharedObject { object_id, .. }) => {
builder.push_record(vec![format!("{i:<3} Shared Object ID: {}", object_id)]);
}
SuiCallArg::Object(SuiObjectArg::Receiving { object_id, .. }) => {
builder.push_record(vec![format!("{i:<3} Receiving Object ID: {}", object_id)]);
if !inputs.is_empty() {
let mut builder = TableBuilder::default();
for (i, input) in inputs.iter().enumerate() {
match input {
SuiCallArg::Pure(v) => {
let pure_arg = if let Some(t) = v.value_type() {
format!(
"{i:<3} Pure Arg: Type: {}, Value: {}",
t,
v.value().to_json_value()
)
} else {
format!("{i:<3} Pure Arg: {}", v.value().to_json_value())
};
builder.push_record(vec![pure_arg]);
}
SuiCallArg::Object(SuiObjectArg::ImmOrOwnedObject { object_id, .. }) => {
builder.push_record(vec![format!(
"{i:<3} Imm/Owned Object ID: {}",
object_id
)]);
}
SuiCallArg::Object(SuiObjectArg::SharedObject { object_id, .. }) => {
builder.push_record(vec![format!(
"{i:<3} Shared Object ID: {}",
object_id
)]);
}
SuiCallArg::Object(SuiObjectArg::Receiving { object_id, .. }) => {
builder.push_record(vec![format!(
"{i:<3} Receiving Object ID: {}",
object_id
)]);
}
}
}

let mut table = builder.build();
table.with(TablePanel::header("Input Objects"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}", table)?;
} else {
write!(f, "\n No input objects for this transaction")?;
}

let mut table = builder.build();
table.with(TablePanel::header("Input Objects"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}", table)?;

let mut builder = TableBuilder::default();

for (i, c) in commands.iter().enumerate() {
if i == commands.len() - 1 {
builder.push_record(vec![format!("{i:<2} {}", Pretty(c))]);
} else {
builder.push_record(vec![format!("{i:<2} {}\n", Pretty(c))]);
if !commands.is_empty() {
let mut builder = TableBuilder::default();
for (i, c) in commands.iter().enumerate() {
if i == commands.len() - 1 {
builder.push_record(vec![format!("{i:<2} {}", Pretty(c))]);
} else {
builder.push_record(vec![format!("{i:<2} {}\n", Pretty(c))]);
}
}
let mut table = builder.build();
table.with(TablePanel::header("Commands"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}", table)
} else {
write!(f, "\n No commands for this transaction")
}
let mut table = builder.build();
table.with(TablePanel::header("Commands"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}", table)
}
}

Expand Down
91 changes: 48 additions & 43 deletions crates/sui-replay/src/displays/transaction_displays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ use tabled::{
/// in these Structs when calling the CLI replay command with an additional provided flag.
impl<'a> Display for Pretty<'a, ProgrammableTransaction> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut builder = TableBuilder::default();

let Pretty(ptb) = self;
let ProgrammableTransaction { inputs, commands } = ptb;

for (i, input) in inputs.iter().enumerate() {
match input {
Pure(v) => {
if v.len() <= 16 {
builder.push_record(vec![format!("{i:<3} Pure Arg {:?}", v)]);
} else {
builder.push_record(vec![format!(
if !inputs.is_empty() {
let mut builder = TableBuilder::default();
for (i, input) in inputs.iter().enumerate() {
match input {
Pure(v) => {
if v.len() <= 16 {
builder.push_record(vec![format!("{i:<3} Pure Arg {:?}", v)]);
} else {
builder.push_record(vec![format!(
"{i:<3} Pure Arg [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, ...]",
v[0],
v[1],
Expand All @@ -45,44 +44,50 @@ impl<'a> Display for Pretty<'a, ProgrammableTransaction> {
v[13],
v[14],
)]);
}
}
}
CallArg::Object(ObjectArg::ImmOrOwnedObject(o)) => {
builder.push_record(vec![format!("{i:<3} Imm/Owned Object ID: {}", o.0)]);
}
CallArg::Object(ObjectArg::SharedObject { id, .. }) => {
builder.push_record(vec![format!("{i:<3} Shared Object ID: {}", id)]);
}
CallArg::Object(ObjectArg::Receiving(o)) => {
builder.push_record(vec![format!("{i:<3} Receiving Object ID: {}", o.0)]);
}
};
}

let mut table = builder.build();
table.with(TablePanel::header("Input Objects"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}\n", table)?;
CallArg::Object(ObjectArg::ImmOrOwnedObject(o)) => {
builder.push_record(vec![format!("{i:<3} Imm/Owned Object ID: {}", o.0)]);
}
CallArg::Object(ObjectArg::SharedObject { id, .. }) => {
builder.push_record(vec![format!("{i:<3} Shared Object ID: {}", id)]);
}
CallArg::Object(ObjectArg::Receiving(o)) => {
builder.push_record(vec![format!("{i:<3} Receiving Object ID: {}", o.0)]);
}
};
}

let mut builder = TableBuilder::default();
let mut table = builder.build();
table.with(TablePanel::header("Input Objects"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}\n", table)?;
} else {
write!(f, "\n No input objects for this transaction")?;
}

for (i, c) in commands.iter().enumerate() {
if i == commands.len() - 1 {
builder.push_record(vec![format!("{i:<2} {}", Pretty(c))]);
} else {
builder.push_record(vec![format!("{i:<2} {}\n", Pretty(c))]);
if !commands.is_empty() {
let mut builder = TableBuilder::default();
for (i, c) in commands.iter().enumerate() {
if i == commands.len() - 1 {
builder.push_record(vec![format!("{i:<2} {}", Pretty(c))]);
} else {
builder.push_record(vec![format!("{i:<2} {}\n", Pretty(c))]);
}
}
let mut table = builder.build();
table.with(TablePanel::header("Commands"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}\n", table)
} else {
write!(f, "\n No commands for this transaction")
}
let mut table = builder.build();
table.with(TablePanel::header("Commands"));
table.with(TableStyle::rounded().horizontals([HorizontalLine::new(
1,
TableStyle::modern().get_horizontal(),
)]));
write!(f, "\n{}\n", table)
}
}

Expand Down

0 comments on commit 266bdf4

Please sign in to comment.