BPF programs can support up to 5 arguments (#2528)
This commit is contained in:
parent
73930b5eac
commit
a0bc8b8af3
|
@ -13,22 +13,21 @@
|
||||||
|
|
||||||
extern bool entrypoint(const uint8_t *input) {
|
extern bool entrypoint(const uint8_t *input) {
|
||||||
SolKeyedAccount ka[NUM_KA];
|
SolKeyedAccount ka[NUM_KA];
|
||||||
const uint8_t *data;
|
SolParameters params = (SolParameters) { .ka = ka };
|
||||||
uint64_t data_len;
|
|
||||||
|
|
||||||
if (!sol_deserialize(input, ka, NUM_KA, NULL, &data, &data_len, NULL)) {
|
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ka[0].is_signer) {
|
if (!params.ka[0].is_signer) {
|
||||||
sol_log("Transaction not signed by key 0");
|
sol_log("Transaction not signed by key 0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tokens = *(int64_t *)data;
|
int64_t tokens = *(int64_t *)params.data;
|
||||||
if (*ka[0].tokens >= tokens) {
|
if (*params.ka[0].tokens >= tokens) {
|
||||||
*ka[0].tokens -= tokens;
|
*params.ka[0].tokens -= tokens;
|
||||||
*ka[2].tokens += tokens;
|
*params.ka[2].tokens += tokens;
|
||||||
// sol_log_64(0, 0, *ka[0].tokens, *ka[2].tokens, tokens);
|
// sol_log_64(0, 0, *ka[0].tokens, *ka[2].tokens, tokens);
|
||||||
} else {
|
} else {
|
||||||
// sol_log_64(0, 0, 0xFF, *ka[0].tokens, tokens);
|
// sol_log_64(0, 0, 0xFF, *ka[0].tokens, tokens);
|
||||||
|
|
|
@ -6,26 +6,17 @@
|
||||||
|
|
||||||
extern bool entrypoint(const uint8_t *input) {
|
extern bool entrypoint(const uint8_t *input) {
|
||||||
SolKeyedAccount ka[1];
|
SolKeyedAccount ka[1];
|
||||||
uint64_t ka_len;
|
SolParameters params = (SolParameters) { .ka = ka };
|
||||||
const uint8_t *data;
|
|
||||||
uint64_t data_len;
|
|
||||||
SolClusterInfo info;
|
|
||||||
|
|
||||||
sol_log(__FILE__);
|
sol_log(__FILE__);
|
||||||
|
|
||||||
if (!sol_deserialize(input, ka, SOL_ARRAY_SIZE(ka), &ka_len, &data, &data_len, &info)) {
|
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol_log("Tick height:");
|
// Log the provided input parameters. In the case of the no-op
|
||||||
sol_log_64(info.tick_height, 0, 0, 0, 0);
|
// program, no account keys or input data are expected but real
|
||||||
sol_log("Program identifier:");
|
|
||||||
sol_log_key(info.program_id);
|
|
||||||
|
|
||||||
// Log the provided account keys and instruction input data. In the case of
|
|
||||||
// the no-op program, no account keys or input data are expected but real
|
|
||||||
// programs will have specific requirements so they can do their work.
|
// programs will have specific requirements so they can do their work.
|
||||||
sol_log("Account keys and instruction input data:");
|
sol_log_params(¶ms);
|
||||||
sol_log_params(ka, ka_len, data, data_len);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,18 @@
|
||||||
|
|
||||||
extern bool entrypoint(const uint8_t *input) {
|
extern bool entrypoint(const uint8_t *input) {
|
||||||
SolKeyedAccount ka[1];
|
SolKeyedAccount ka[1];
|
||||||
uint64_t ka_len;
|
SolParameters params = (SolParameters) { .ka = ka };
|
||||||
const uint8_t *data;
|
|
||||||
uint64_t data_len;
|
|
||||||
SolClusterInfo info;
|
|
||||||
|
|
||||||
sol_log(__FILE__);
|
sol_log(__FILE__);
|
||||||
|
|
||||||
if (!sol_deserialize(input, ka, SOL_ARRAY_SIZE(ka), &ka_len, &data, &data_len, &info)) {
|
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sol_log("Tick height:");
|
|
||||||
sol_log_64(info.tick_height, 0, 0, 0, 0);
|
|
||||||
sol_log("Program identifier:");
|
|
||||||
sol_log_key(info.program_id);
|
|
||||||
|
|
||||||
// Log the provided account keys and instruction input data. In the case of
|
// Log the provided input parameters. In the case of the no-op
|
||||||
// the no-op program, no account keys or input data are expected but real
|
// program, no account keys or input data are expected but real
|
||||||
// programs will have specific requirements so they can do their work.
|
// programs will have specific requirements so they can do their work.
|
||||||
sol_log("Account keys and instruction input data:");
|
sol_log_params(¶ms);
|
||||||
sol_log_params(ka, ka_len, data, data_len);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,18 +186,22 @@ SOL_FN_PREFIX void _sol_panic(uint64_t line) {
|
||||||
* Asserts
|
* Asserts
|
||||||
*/
|
*/
|
||||||
#define sol_assert(expr) \
|
#define sol_assert(expr) \
|
||||||
if (!(expr)) { \
|
if (!(expr)) { \
|
||||||
_sol_panic(__LINE__); \
|
_sol_panic(__LINE__); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about the state of the cluster immediately before the program
|
* Structure that the program's entrypoint input data is deserialized into.
|
||||||
* started executing the current instruction
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
SolKeyedAccount* ka; /** Pointer to an array of SolKeyedAccount, must already
|
||||||
|
point to an array of SolKeyedAccounts */
|
||||||
|
uint64_t ka_num; /** Number of SolKeyedAccount entries in `ka` */
|
||||||
|
const uint8_t *data; /** pointer to the instruction data */
|
||||||
|
uint64_t data_len; /** Length in bytes of the instruction data */
|
||||||
uint64_t tick_height; /** Current ledger tick */
|
uint64_t tick_height; /** Current ledger tick */
|
||||||
const SolPubkey *program_id; /** program_id of the currently executing program */
|
const SolPubkey *program_id; /** program_id of the currently executing program */
|
||||||
} SolClusterInfo;
|
} SolParameters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* De-serializes the input parameters into usable types
|
* De-serializes the input parameters into usable types
|
||||||
|
@ -210,72 +214,55 @@ typedef struct {
|
||||||
* at program end.
|
* at program end.
|
||||||
*
|
*
|
||||||
* @param input Source buffer containing serialized input parameters
|
* @param input Source buffer containing serialized input parameters
|
||||||
* @param ka Pointer to an array of SolKeyedAccount to deserialize into
|
* @param params Pointer to a SolParameters structure
|
||||||
* @param ka_len Number of SolKeyedAccount entries in `ka`
|
* @return Boolean true if successful.
|
||||||
* @param ka_len_out If NULL, fill exactly `ka_len` accounts or fail.
|
|
||||||
* If not NULL, fill up to `ka_len` accounts and return the
|
|
||||||
* number of filled accounts in `ka_len_out`.
|
|
||||||
* @param data On return, a pointer to the instruction data
|
|
||||||
* @param data_len On return, the length in bytes of the instruction data
|
|
||||||
* @param cluster_info If not NULL, fill cluster_info
|
|
||||||
* @return Boolean true if successful
|
|
||||||
*/
|
*/
|
||||||
SOL_FN_PREFIX bool sol_deserialize(
|
SOL_FN_PREFIX bool sol_deserialize(
|
||||||
const uint8_t *input,
|
const uint8_t *input,
|
||||||
SolKeyedAccount *ka,
|
SolParameters *params,
|
||||||
uint64_t ka_len,
|
uint64_t ka_num
|
||||||
uint64_t *ka_len_out,
|
|
||||||
const uint8_t **data,
|
|
||||||
uint64_t *data_len,
|
|
||||||
SolClusterInfo *cluster_info
|
|
||||||
) {
|
) {
|
||||||
if (ka_len_out == NULL) {
|
if (NULL == input || NULL == params) {
|
||||||
if (ka_len != *(uint64_t *) input) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ka_len = *(uint64_t *) input;
|
params->ka_num = *(uint64_t *) input;
|
||||||
} else {
|
if (ka_num < *(uint64_t *) input) {
|
||||||
if (ka_len > *(uint64_t *) input) {
|
return false;
|
||||||
ka_len = *(uint64_t *) input;
|
|
||||||
}
|
|
||||||
*ka_len_out = ka_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
for (int i = 0; i < ka_len; i++) {
|
for (int i = 0; i < params->ka_num; i++) {
|
||||||
// key
|
// key
|
||||||
ka[i].is_signer = *(uint64_t *) input != 0;
|
params->ka[i].is_signer = *(uint64_t *) input != 0;
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
ka[i].key = (SolPubkey *) input;
|
params->ka[i].key = (SolPubkey *) input;
|
||||||
input += sizeof(SolPubkey);
|
input += sizeof(SolPubkey);
|
||||||
|
|
||||||
// tokens
|
// tokens
|
||||||
ka[i].tokens = (uint64_t *) input;
|
params->ka[i].tokens = (uint64_t *) input;
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
|
|
||||||
// account userdata
|
// account userdata
|
||||||
ka[i].userdata_len = *(uint64_t *) input;
|
params->ka[i].userdata_len = *(uint64_t *) input;
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
ka[i].userdata = (uint8_t *) input;
|
params->ka[i].userdata = (uint8_t *) input;
|
||||||
input += ka[i].userdata_len;
|
input += params->ka[i].userdata_len;
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
ka[i].owner = (SolPubkey *) input;
|
params->ka[i].owner = (SolPubkey *) input;
|
||||||
input += sizeof(SolPubkey);
|
input += sizeof(SolPubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// input data
|
params->data_len = *(uint64_t *) input;
|
||||||
*data_len = *(uint64_t *) input;
|
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
*data = input;
|
params->data = input;
|
||||||
input += *data_len;
|
input += params->data_len;
|
||||||
|
|
||||||
if (cluster_info != NULL) {
|
params->tick_height = *(uint64_t *) input;
|
||||||
cluster_info->tick_height = *(uint64_t *) input;
|
|
||||||
input += sizeof(uint64_t);
|
input += sizeof(uint64_t);
|
||||||
cluster_info->program_id = (SolPubkey *) input;
|
params->program_id = (SolPubkey *) input;
|
||||||
input += sizeof(SolPubkey);
|
input += sizeof(SolPubkey);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,35 +294,32 @@ SOL_FN_PREFIX void sol_log_array(const uint8_t *array, int len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the hexadecimal representation of the program's input parameters
|
* Prints the program's input parameters
|
||||||
*
|
*
|
||||||
* @param ka A pointer to an array of SolKeyedAccount to print
|
* @param params Pointer to a SolParameters structure
|
||||||
* @param ka_len Number of SolKeyedAccount to print
|
|
||||||
* @param data A pointer to the instruction data to print
|
|
||||||
* @param data_len The length in bytes of the instruction data
|
|
||||||
*/
|
*/
|
||||||
SOL_FN_PREFIX void sol_log_params(
|
SOL_FN_PREFIX void sol_log_params(const SolParameters *params) {
|
||||||
const SolKeyedAccount *ka,
|
sol_log("- Tick height:");
|
||||||
uint64_t ka_len,
|
sol_log_64(params->tick_height, 0, 0, 0, 0);
|
||||||
const uint8_t *data,
|
sol_log("- Program identifier:");
|
||||||
uint64_t data_len
|
sol_log_key(params->program_id);
|
||||||
) {
|
|
||||||
sol_log("- Number of KeyedAccounts");
|
sol_log("- Number of KeyedAccounts");
|
||||||
sol_log_64(0, 0, 0, 0, ka_len);
|
sol_log_64(0, 0, 0, 0, params->ka_num);
|
||||||
for (int i = 0; i < ka_len; i++) {
|
for (int i = 0; i < params->ka_num; i++) {
|
||||||
sol_log("- Is signer");
|
sol_log(" - Is signer");
|
||||||
sol_log_64(0, 0, 0, 0, ka[i].is_signer);
|
sol_log_64(0, 0, 0, 0, params->ka[i].is_signer);
|
||||||
sol_log("- Key");
|
sol_log(" - Key");
|
||||||
sol_log_key(ka[i].key);
|
sol_log_key(params->ka[i].key);
|
||||||
sol_log("- Tokens");
|
sol_log(" - Tokens");
|
||||||
sol_log_64(0, 0, 0, 0, *ka[i].tokens);
|
sol_log_64(0, 0, 0, 0, *params->ka[i].tokens);
|
||||||
sol_log("- Userdata");
|
sol_log(" - Userdata");
|
||||||
sol_log_array(ka[i].userdata, ka[i].userdata_len);
|
sol_log_array(params->ka[i].userdata, params->ka[i].userdata_len);
|
||||||
sol_log("- Owner");
|
sol_log(" - Owner");
|
||||||
sol_log_key(ka[i].owner);
|
sol_log_key(params->ka[i].owner);
|
||||||
}
|
}
|
||||||
sol_log("- Instruction data\0");
|
sol_log("- Instruction data\0");
|
||||||
sol_log_array(data, data_len);
|
sol_log_array(params->data, params->data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
Loading…
Reference in New Issue