| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #pragma once
- /**
- * @brief Solana SBF loader deserializer to be used when deploying
- * a program with `SBFLoader2111111111111111111111111111111111` or
- * `SBFLoaderUpgradeab1e11111111111111111111111`
- */
- #include <sol/types.h>
- #include <sol/pubkey.h>
- #include <sol/entrypoint.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * Maximum number of bytes a program may add to an account during a single realloc
- */
- #define MAX_PERMITTED_DATA_INCREASE (1024 * 10)
- /**
- * De-serializes the input parameters into usable types
- *
- * Use this function to deserialize the buffer passed to the program entrypoint
- * into usable types. This function does not perform copy deserialization,
- * instead it populates the pointers and lengths in SolAccountInfo and data so
- * that any modification to lamports or account data take place on the original
- * buffer. Doing so also eliminates the need to serialize back into the buffer
- * at the end of the program.
- *
- * @param input Source buffer containing serialized input parameters
- * @param params Pointer to a SolParameters structure
- * @return Boolean true if successful.
- */
- static bool sol_deserialize(
- const uint8_t *input,
- SolParameters *params,
- uint64_t ka_num
- ) {
- if (NULL == input || NULL == params) {
- return false;
- }
- params->ka_num = *(uint64_t *) input;
- input += sizeof(uint64_t);
- for (int i = 0; i < params->ka_num; i++) {
- uint8_t dup_info = input[0];
- input += sizeof(uint8_t);
- if (i >= ka_num) {
- if (dup_info == UINT8_MAX) {
- input += sizeof(uint8_t);
- input += sizeof(uint8_t);
- input += sizeof(uint8_t);
- input += 4; // padding
- input += sizeof(SolPubkey);
- input += sizeof(SolPubkey);
- input += sizeof(uint64_t);
- uint64_t data_len = *(uint64_t *) input;
- input += sizeof(uint64_t);
- input += data_len;
- input += MAX_PERMITTED_DATA_INCREASE;
- input = (uint8_t*)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
- input += sizeof(uint64_t);
- } else {
- input += 7; // padding
- }
- continue;
- }
- if (dup_info == UINT8_MAX) {
- // is signer?
- params->ka[i].is_signer = *(uint8_t *) input != 0;
- input += sizeof(uint8_t);
- // is writable?
- params->ka[i].is_writable = *(uint8_t *) input != 0;
- input += sizeof(uint8_t);
- // executable?
- params->ka[i].executable = *(uint8_t *) input;
- input += sizeof(uint8_t);
- input += 4; // padding
- // key
- params->ka[i].key = (SolPubkey *) input;
- input += sizeof(SolPubkey);
- // owner
- params->ka[i].owner = (SolPubkey *) input;
- input += sizeof(SolPubkey);
- // lamports
- params->ka[i].lamports = (uint64_t *) input;
- input += sizeof(uint64_t);
- // account data
- params->ka[i].data_len = *(uint64_t *) input;
- input += sizeof(uint64_t);
- params->ka[i].data = (uint8_t *) input;
- input += params->ka[i].data_len;
- input += MAX_PERMITTED_DATA_INCREASE;
- input = (uint8_t*)(((uint64_t)input + 8 - 1) & ~(8 - 1)); // padding
- // rent epoch
- params->ka[i].rent_epoch = *(uint64_t *) input;
- input += sizeof(uint64_t);
- } else {
- params->ka[i].is_signer = params->ka[dup_info].is_signer;
- params->ka[i].is_writable = params->ka[dup_info].is_writable;
- params->ka[i].executable = params->ka[dup_info].executable;
- params->ka[i].key = params->ka[dup_info].key;
- params->ka[i].owner = params->ka[dup_info].owner;
- params->ka[i].lamports = params->ka[dup_info].lamports;
- params->ka[i].data_len = params->ka[dup_info].data_len;
- params->ka[i].data = params->ka[dup_info].data;
- params->ka[i].rent_epoch = params->ka[dup_info].rent_epoch;
- input += 7; // padding
- }
- }
- params->data_len = *(uint64_t *) input;
- input += sizeof(uint64_t);
- params->data = input;
- input += params->data_len;
- params->program_id = (SolPubkey *) input;
- input += sizeof(SolPubkey);
- return true;
- }
- #ifdef __cplusplus
- }
- #endif
- /**@}*/
|