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

refactor(decode-base64): clean code improvements and fn docs #1754

Merged
merged 3 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#1723](https://github.com/NibiruChain/nibiru/pull/1723) - ci(e2e-wasm.yml): rm unused workflow
* [#1728](https://github.com/NibiruChain/nibiru/pull/1728) - test(devgas-cli): CLI tests for devgas txs
* [#1735](https://github.com/NibiruChain/nibiru/pull/1735) - test(sim): fix simulation tests
* [#1754](https://github.com/NibiruChain/nibiru/pull/1754) - refactor(decode-base64): clean code improvements and fn docs

### Dependencies
- Bump `github.com/prometheus/client_golang` from 1.17.0 to 1.18.0 ([#1750](https://github.com/NibiruChain/nibiru/pull/1750))
Expand Down
84 changes: 65 additions & 19 deletions cmd/nibid/cmd/decode_base64.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,39 @@
wasmvm "github.com/CosmWasm/wasmvm/types"
)

// YieldStargateMsgs parses the JSON and sends wasmvm.StargateMsg objects to a channel
func YieldStargateMsgs(jsonBz []byte) ([]wasmvm.StargateMsg, error) {
// YieldStargateMsgs takes a byte slice of JSON data and converts it into a slice
// of wasmvm.StargateMsg objects. This function is essential for processing
// JSON-formatted messages that contain base64-encoded protobuf messages.
//
// Args:
// - jsonBz []byte: A byte slice containing the JSON data to be parsed.
//
// Returns:
// - sgMsgs []wasmvm.StargateMsg: A slice of wasmvm.StargateMsg objects parsed
// from the provided JSON data.
// - err error: An error object, which is nil if the operation is successful.
func YieldStargateMsgs(jsonBz []byte) (sgMsgs []wasmvm.StargateMsg, err error) {
var data interface{}
if err := json.Unmarshal(jsonBz, &data); err != nil {
return nil, err
return sgMsgs, err
k-yang marked this conversation as resolved.
Show resolved Hide resolved
}

Check warning on line 33 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L32-L33

Added lines #L32 - L33 were not covered by tests

var msgs []wasmvm.StargateMsg
parseStargateMsgs(data, &msgs)
return msgs, nil
parseStargateMsgs(data, &sgMsgs)
return sgMsgs, nil
}

// parseStargateMsgs is a recursive function used by YieldStargateMsgs to
// traverse the JSON data, filter for any protobuf.Any messages in the
// "WasmVM.StargateMsg" format and decode them from base64 back to human-readable
// form as JSON objects.
//
// Args:
// - jsonData any: JSON data to parse. According to the JSON specification,
// possible value types are:
// Null, Bool, Number(f64), String, Array, or Object(Map<String, Value>)
// - msgs *[]wasmvm.StargateMsg: Mutable reference to a slice of protobuf
// messages. These are potentially altered in place if the value is an
// encoded base 64 string.
Comment on lines +39 to +50
Copy link
Contributor

Choose a reason for hiding this comment

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

The parseStargateMsgs function lacks error handling. If the base64 decoding fails or the JSON marshaling encounters an issue, the function should return an error instead of silently failing. This is crucial for debugging and ensuring data integrity.

func parseStargateMsgs(jsonData any, msgs *[]wasmvm.StargateMsg) error {
  // ... existing code ...
+ if _, err := base64.StdEncoding.DecodeString(valueStr); err != nil {
+   return fmt.Errorf("failed to decode base64 value: %w", err)
+ }
  // ... existing code ...
+ return nil
}

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// parseStargateMsgs is a recursive function used by YieldStargateMsgs to
// traverse the JSON data, filter for any protobuf.Any messages in the
// "WasmVM.StargateMsg" format and decode them from base64 back to human-readable
// form as JSON objects.
//
// Args:
// - jsonData any: JSON data to parse. According to the JSON specification,
// possible value types are:
// Null, Bool, Number(f64), String, Array, or Object(Map<String, Value>)
// - msgs *[]wasmvm.StargateMsg: Mutable reference to a slice of protobuf
// messages. These are potentially altered in place if the value is an
// encoded base 64 string.
func parseStargateMsgs(jsonData any, msgs *[]wasmvm.StargateMsg) error {
// ... existing code ...
if _, err := base64.StdEncoding.DecodeString(valueStr); err != nil {
return fmt.Errorf("failed to decode base64 value: %w", err)
}
// ... existing code ...
return nil
}

func parseStargateMsgs(jsonData any, msgs *[]wasmvm.StargateMsg) {
switch v := jsonData.(type) {
case map[string]interface{}:
Expand All @@ -41,69 +62,93 @@
for _, value := range v {
parseStargateMsgs(value, msgs)
}
case []interface{}:
for _, value := range v {
parseStargateMsgs(value, msgs)
}

Check warning on line 68 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L65-L68

Added lines #L65 - L68 were not covered by tests
}
}

// StargateMsgDecoded is a struct designed to hold a decoded version of a
// "wasmvm.StargateMsg".
type StargateMsgDecoded struct {
TypeURL string `json:"type_url"`
Value string `json:"value"`
}

// DecodeBase64StargateMsgs decodes a series of base64-encoded
// wasmvm.StargateMsg objects from the provided JSON byte slice (jsonBz).
// This function is vital for extracting and interpreting the contents of these
// protobuf messages.
//
// Args:
// - jsonBz []byte: JSON data containing potential base64-encoded messages.
// - clientCtx client.Context: Context for the `nibid` CLI.
//
// Returns:
// - newSgMsgs []StargateMsgDecoded: The decoded stargate messages.
// - err error: An error object, which is nil if the operation is successful.
func DecodeBase64StargateMsgs(
jsonBz []byte, context client.Context,
jsonBz []byte, clientCtx client.Context,
k-yang marked this conversation as resolved.
Show resolved Hide resolved
) (newSgMsgs []StargateMsgDecoded, err error) {
codec := context.Codec
codec := clientCtx.Codec

var data interface{}
if err := json.Unmarshal(jsonBz, &data); err != nil {
return []StargateMsgDecoded{}, err
return newSgMsgs, fmt.Errorf(
"failed to decode stargate msgs due to invalid JSON: %w", err)
}

sgMsgs, err := YieldStargateMsgs(jsonBz)
if err != nil {
return
return newSgMsgs, err
Unique-Divine marked this conversation as resolved.
Show resolved Hide resolved
}

Check warning on line 105 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L104-L105

Added lines #L104 - L105 were not covered by tests
for _, sgMsg := range sgMsgs {
valueStr := string(sgMsg.Value)
value := strings.Replace(string(sgMsg.Value), `\"`, `"`, -1)
value = strings.Replace(value, `"{`, `{`, -1)
value = strings.Replace(value, `}"`, `}`, -1)
replacer := strings.NewReplacer(
`\"`, `"`, // old, new
`"{`, `{`,
`}"`, `}`,
)
value := replacer.Replace(string(sgMsg.Value))

if _, err := base64.StdEncoding.DecodeString(valueStr); err == nil {
protoMsg, err := context.InterfaceRegistry.Resolve(sgMsg.TypeURL)
protoMsg, err := clientCtx.InterfaceRegistry.Resolve(sgMsg.TypeURL)
if err != nil {
return newSgMsgs, err
}

Check warning on line 119 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L118-L119

Added lines #L118 - L119 were not covered by tests
Unique-Divine marked this conversation as resolved.
Show resolved Hide resolved

decodedBz, _ := base64.StdEncoding.Strict().DecodeString(string(sgMsg.Value))
concrete := protoMsg.(sdkcodec.ProtoMarshaler)

err = codec.Unmarshal(decodedBz, concrete)
if err != nil {
return newSgMsgs, err
}

Check warning on line 127 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L126-L127

Added lines #L126 - L127 were not covered by tests

outBytes, err := codec.MarshalJSON(concrete)
if err != nil {
return newSgMsgs, err
}

Check warning on line 132 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L131-L132

Added lines #L131 - L132 were not covered by tests

newSgMsgs = append(newSgMsgs, StargateMsgDecoded{sgMsg.TypeURL, string(outBytes)})
newSgMsgs = append(newSgMsgs,
StargateMsgDecoded{sgMsg.TypeURL, string(outBytes)},
)
} else if _, err := json.Marshal(value); err == nil {
newSgMsgs = append(newSgMsgs, StargateMsgDecoded{sgMsg.TypeURL, string(sgMsg.Value)})
newSgMsgs = append(newSgMsgs,
StargateMsgDecoded{sgMsg.TypeURL, string(sgMsg.Value)},
)
Unique-Divine marked this conversation as resolved.
Show resolved Hide resolved
} else {
return newSgMsgs, fmt.Errorf(
"parse error: encountered wasmvm.StargateMsg with unexpected format: %s", sgMsg)
}

Check warning on line 144 in cmd/nibid/cmd/decode_base64.go

View check run for this annotation

Codecov / codecov/patch

cmd/nibid/cmd/decode_base64.go#L142-L144

Added lines #L142 - L144 were not covered by tests
}
return newSgMsgs, nil
}

// DecodeBase64Cmd creates a cobra command for base64 decoding.
// DecodeBase64Cmd creates a Cobra command used to decode base64-encoded protobuf
// messages from a JSON input. This function enables users to input arbitrary
// JSON strings and parse the contents of base-64 encoded protobuf.Any messages.
func DecodeBase64Cmd(defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Use: "base64-decode",
Expand All @@ -114,8 +159,9 @@
clientCtx := client.GetClientContextFromCmd(cmd)

outMessage, err := DecodeBase64StargateMsgs([]byte(args[0]), clientCtx)
fmt.Println(outMessage)

if err == nil {
fmt.Println(outMessage)
}
return err
Unique-Divine marked this conversation as resolved.
Show resolved Hide resolved
},
}
Expand Down
Loading