Skip to content

add custom JSON marshaling for DefaultMetadata #72

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

Closed
wants to merge 4 commits into from

Conversation

akuzni2
Copy link
Contributor

@akuzni2 akuzni2 commented May 8, 2025

Added a custom MarshalJSON method to DefaultMetadata. This ensures that if the Data field contains JSON, it is not double-encoded, while non-JSON data is marshaled as-is.

@akuzni2 akuzni2 requested a review from a team as a code owner May 8, 2025 22:24
Copy link

changeset-bot bot commented May 8, 2025

🦋 Changeset detected

Latest commit: 6ad0a2b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
chainlink-deployments-framework Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@akuzni2 akuzni2 force-pushed the data-store/default-metadata-marshal-json branch from 59ecf68 to 6137389 Compare May 8, 2025 22:26
@akuzni2 akuzni2 force-pushed the data-store/default-metadata-marshal-json branch from 6137389 to a167228 Compare May 8, 2025 22:30
Copy link
Collaborator

@graham-chainlink graham-chainlink left a comment

Choose a reason for hiding this comment

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

You got a lint error

@akuzni2 akuzni2 enabled auto-merge May 8, 2025 23:22

// MarshalJSON can handle both JSON and non-JSON data in the Data field.
// Without custom marshaling, the Data field would be double-encoded if it contains JSON.
func (dm DefaultMetadata) MarshalJSON() ([]byte, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Then unmarshaling would not work right since the Json can't be converted back to a string unless we implement Unmarshaljson too? Let me check with @giogam to understand this a bit more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point - we'd need to implement that

Copy link
Contributor

@giogam giogam May 9, 2025

Choose a reason for hiding this comment

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

Hey @akuzni2! Can you provide more context on why this is necessary? The Data field is intended to store a JSON-encoded string representing a domain-specific metadata type, so there shouldn’t be a need to store non-JSON data.

Copy link
Contributor Author

@akuzni2 akuzni2 May 9, 2025

Choose a reason for hiding this comment

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

@giogam

there shouldn’t be a need to store non-JSON data.

This is I believe the intent as well.

Without correct serialization JSON is double escaped.

       {
          "contractMetadataStore": {
            "records": [
              {
                "address": "0x1234",
                "chainSelector": 3478487238524512106,
                "metadata": {
                  "data": "{\"content\":{\"metadata\":{\"deployBlock\":150906864},\"view\":{\"field1\":[\"0x1234567890abcdef\"],\"field2\":{\"key1\":\"value1\"}}}}"
                }
              }
            ]
          },
        }

With this custom serializer in this PR

       {
          "contractMetadataStore": {
            "records": [
              {
                "address": "0x1234",
                "chainSelector": 3478487238524512106,
                "metadata": {
                  "data": {
                    "content": {
                      "metadata": {
                        "deployBlock": 150906864
                      },
                      "view": {
                        "field1": [
                          "0x1234567890abcdef"
                        ],
                        "field2": {
                          "key1": "value1"
                        }
                      }
                    }
                  }
                }
              }
            ]
          },
        }   

Isn't this the intended format if the whole output should be serialized to JSON?

The double escaping is happening now because ToDefault does a cast string(data)

if the Data field of DefaultMetadata is really intended to be JSON - we should change this to Go's json.RawMessage which will handle the double encoding for us.

So theres 2 choices:

  1. custom serialization (implemented in PR)
  2. break the data-type and hope no one is using it directly and go and update it everywhere

@akuzni2 akuzni2 requested review from giogam and graham-chainlink May 9, 2025 18:25
@graham-chainlink
Copy link
Collaborator

Thanks Alex, I will leave this to @giogam as he has a lot more context on the design of datastore.

@giogam giogam disabled auto-merge June 5, 2025 09:40
@giogam
Copy link
Contributor

giogam commented Jun 5, 2025

@giogam giogam closed this Jun 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants