Issue: invoke_transfer_checked
failed with out of memory for 2 transfers with hook #7004
Description
Problem:
It is possible to brake external programs which use token extension with transfer hook if it requires more than 6 additional extra account meta.
sdk function invoke_transfer_checked
use some part of data allocation on heap with Vector
by pushing new elements into it dynamically while resolving extra account meta data.
So I suppose that during the preparation of accounts for extra accounts and pushing into Vectors it consumes a huge portion of heap memory.
Vectors creation:
- https://github.com/solana-labs/solana-program-library/blob/master/token/program-2022/src/onchain.rs#L42
- https://github.com/solana-labs/solana-program-library/blob/master/token/transfer-hook/interface/src/onchain.rs#L98
Pushing into vectors:
- https://github.com/solana-labs/solana-program-library/blob/master/token/program-2022/src/onchain.rs#L54
- https://github.com/solana-labs/solana-program-library/blob/master/token/program-2022/src/onchain.rs#L55
- https://github.com/solana-labs/solana-program-library/blob/master/libraries/tlv-account-resolution/src/state.rs#L365
- https://github.com/solana-labs/solana-program-library/blob/master/libraries/tlv-account-resolution/src/state.rs#L364
The simple transfer hook program which fails with the out of memory
due to intensive allocation inside invoke_transfer_checked
https://github.com/makarychev/solana-transfer-extensions/
Failing integration test: https://github.com/makarychev/solana-transfer-extensions/actions/runs/9844698072/job/27178656558#step:9:74
Program log: Error: memory allocation failed, out of memory
Instruction code: https://github.com/makarychev/solana-transfer-extensions/blob/main/programs/transfer-extensions/src/instructions/multi_transfers.rs#L40
Transfer Hook code: https://github.com/makarychev/solana-transfer-extensions/blob/main/programs/transfer-hook/src/instructions/handler.rs#L41
Questions:
How can we send 2 transfers from 1 external program instruction if transfer hook has 8 extra account? Does transfer with transfer hook execution have constraint on extra accounts count?
Could invoke_transfer_checked
be optimized or in such scenario or it is required to fill extra accounts manually (not by invoke_transfer_checked
)?
Probably it is possible to execute transfer with transfer hook more efficient?