solana icon indicating copy to clipboard operation
solana copied to clipboard

Simulate Transaction doesn't return Token accounts with JSON encoding

Open mcintyre94 opened this issue 1 year ago • 3 comments

Problem

Take this example simulateTransaction RPC call on devnet:

{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "simulateTransaction",
    "params": [
        "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQHGThNI65OhkvOGV+DlO4hQdc0U6joPE4az8wnRhU/zZe0aDLGa0cy16lBWIf9ij+BU6eobQjtSBAP3ZRNOzSRTLxPOmj5LXZb8EVEBvpSsLG9P9kYCYqlowhFVOefwFCYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpKDlVCWX/1NZKyq9G1F33MY5bT1fJDEh9YGJdgpuDewVKU1qZKSEGTSTocWDaOHx8NbXdvJK7geQfqEBBBUSNBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKmOYFcfFz0Vu4XMA4jr8WltA1R3YRYSEipAl9FD4qy+FgMFAAY0RkhkVEwDAgAADAIAAAAAAAAAAAAAAAYEAgQBAAoMoIYBAAAAAAAG",
        {
            "commitment": "confirmed",
            "encoding": "base64",
            "sigVerify": false,
            "replaceRecentBlockhash": true,
            "accounts": {
                "addresses": [
                    "D9EYGf9etBGpPLHwiKMpxzn8gcHZapP6uvakAiCkdapK",
                    "Dg5iatJR92aPAZ6E9kBCrdb2DDeaPoQdexjC48MrvNGf"
                ],
                "encoding": "jsonParsed"
            }
        }
    ]
}

The two addresses are token accounts. This should return jsonParsed accounts, but it doesn't:

            "accounts": [
                {
                    "data": [
                        "6Sg5VQll/9TWSsqvRtRd9zGOW09XyQxIfWBiXYKbg3vbLzrNfN5YZjAai4m3oURtvycuDlQ8wTPq3YIlZUPQ9Egxxy0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                        "base64"
                    ],
                    "executable": false,
                    "lamports": 2039280,
                    "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "rentEpoch": 18446744073709551615,
                    "space": 165
                },
                {
                    "data": [
                        "6Sg5VQll/9TWSsqvRtRd9zGOW09XyQxIfWBiXYKbg3sZOE0jrk6GS84ZX4OU7iFB1zRTqOg8ThrPzCdGFT/Nl2Ba9AUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                        "base64"
                    ],
                    "executable": false,
                    "lamports": 2039280,
                    "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "rentEpoch": 18446744073709551615,
                    "space": 165
                }
            ],

You can see both accounts are owned by the token program. A getAccountInfo call on either account with jsonParsed encoding works correctly:

            "data": {
                "parsed": {
                    "info": {
                        "isNative": false,
                        "mint": "Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr",
                        "owner": "Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB",
                        "state": "initialized",
                        "tokenAmount": {
                            "amount": "767929000",
                            "decimals": 6,
                            "uiAmount": 767.929,
                            "uiAmountString": "767.929"
                        }
                    },
                    "type": "account"
                },
                "program": "spl-token",
                "space": 165
            },

Proposed Solution

The bug is caused by not passing AccountAdditionalData on this code path.

In encode_account we pass additional_data: None to UiAccount::encode (4th arg): https://github.com/solana-labs/solana/blob/30fa449a33af7fd59a2528c64f466df4df58f5a8/rpc/src/rpc.rs#L2320-L2322

This gets passed through to parse_account_data, which passes mint_decimals: None to parse_token: https://github.com/solana-labs/solana/blob/30fa449a33af7fd59a2528c64f466df4df58f5a8/account-decoder/src/parse_account_data.rs#L111-L113

This then errors when it's unable to read mint decimals: https://github.com/solana-labs/solana/blob/30fa449a33af7fd59a2528c64f466df4df58f5a8/account-decoder/src/parse_token.rs#L65-L69

And we fall back to returning base64 instead: https://github.com/solana-labs/solana/blob/30fa449a33af7fd59a2528c64f466df4df58f5a8/account-decoder/src/lib.rs#L142-L153

I haven't looked at how we do this for eg getAccountInfo, but assuming most of this code is shared we must be getting the mint decimals in AccountAdditionalData and passing that through. We need to do the same for simulateTransaction to enable returning JSON parsed token accounts.

mcintyre94 avatar Jan 08 '24 17:01 mcintyre94

@mcintyre94 good shout! I can pick this up.

buffalojoec avatar Jan 08 '24 19:01 buffalojoec

There is already an existing PR to fix this issue: https://github.com/solana-labs/solana/pull/34619 We're still deciding on the exact implementation.

CriesofCarrots avatar Jan 08 '24 20:01 CriesofCarrots

Can this issue be resolved? Looks like the fix was merged in

joncinque avatar Jan 26 '24 23:01 joncinque

Sorry yep! Fixed by https://github.com/solana-labs/solana/pull/34619

mcintyre94 avatar Jan 31 '24 22:01 mcintyre94