solana
solana copied to clipboard
Simulate Transaction doesn't return Token accounts with JSON encoding
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 good shout! I can pick this up.
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.
Can this issue be resolved? Looks like the fix was merged in
Sorry yep! Fixed by https://github.com/solana-labs/solana/pull/34619