gagliardetto / solana-go

Go SDK library and RPC client for the Solana Blockchain
Apache License 2.0
943 stars 267 forks source link

data bytes or json from bytes #90

Closed DimaCantemir closed 2 years ago

DimaCantemir commented 2 years ago

added ability to create DataBytesOrJSON struct directly from base64 bytes. Useful when you receive an account though alternative channels, like Geyser plugin + graph protocol, and need to reconstruct it with as little overhead as possible

aspin commented 2 years ago

could we get a bump on this @gagliardetto ?

gagliardetto commented 2 years ago

Wait, I'm actually not sure what are you trying to do here.

gagliardetto commented 2 years ago

Can you make an example of a scenario? (with data)

DimaCantemir commented 2 years ago

You had this function before:

func DataBytesOrJSONFromBase64(stringBase64 string) (*DataBytesOrJSON, error) {
    decoded, err := base64.StdEncoding.DecodeString(stringBase64)
    if err != nil {
        return nil, err
    }
    return DataBytesOrJSONFromBase64Bytes(decoded)
}

but we are getting a stream of binary encoded Accounts from a Geyser plugin stream and we have the Data field of the Accounts already in a []byte format so to create a DataBytesOrJSON struct we need to encode the bytes into string and then you function above decodes it back. With our PR we introduce a way to avoid this encode decode nonsense and create a DataBytesOrJSON struct directly from a slice of bytes

gagliardetto commented 2 years ago

Which is it:

A) You have plain account binary data (not base64/base58/json encoded).

B) You have account data that's base64-encoded, BUT it's not a string but bytes.

DimaCantemir commented 2 years ago

B)

gagliardetto commented 2 years ago

In that case, your PR content won't solve your problem.

Can't you just DataBytesOrJSONFromBase64(string(encodedData)) ?

DimaCantemir commented 2 years ago

in fact let me give you what you asked for - an example. Here's our code:

dataB64 := base64.StdEncoding.EncodeToString(response.Data)
    db, err := solanarpc.DataBytesOrJSONFromBase64(dataB64)
    if err != nil {
        return nil, fmt.Errorf("could not parse data: %w", err)
    }

    keyedAccount := &solanarpc.KeyedAccount{
        Pubkey: pk,
        Account: &solanarpc.Account{
            Lamports:   response.Lamports,
            Owner:      ownerPk,
            Data:       db,
            Executable: response.Executable,
            RentEpoch:  response.RentEpoch,
        },
    }
gagliardetto commented 2 years ago

In that case you have the A case, and need to create a DataBytesOrJSON. I see.

DimaCantemir commented 2 years ago

this last push should do it. thanks for your time and this package overall

gagliardetto commented 2 years ago

LGTM, just need to address the couple above naming changes.

DimaCantemir commented 2 years ago

Done

gagliardetto commented 2 years ago

Still missing the change in the comment.

If you go to the "Files changed" tab, you can commit suggestions directly.

DimaCantemir commented 2 years ago

Done. When you merge this could you please tag a new release ? our devOps people are itching to run some performance tests after we integrate this change

gagliardetto commented 2 years ago

No release is scheduled for today.

You can use the latest source with your changes by go get github.com/gagliardetto/solana-go@8bd6977469ecb5bbd8a27488648b82bd1904f5fe