Files
solana/programs/bpf/c/src/invoked/invoked.c

176 lines
6.9 KiB
C
Raw Normal View History

2020-04-28 14:33:56 -07:00
/**
2020-05-08 12:24:36 -07:00
* @brief Example C-based BPF program that tests cross-program invocations
2020-04-28 14:33:56 -07:00
*/
2020-05-08 12:24:36 -07:00
#include "instruction.h"
2020-04-28 14:33:56 -07:00
#include <solana_sdk.h>
extern uint64_t entrypoint(const uint8_t *input) {
SolAccountInfo accounts[4];
SolParameters params = (SolParameters){.ka = accounts};
if (!sol_deserialize(input, &params, 0)) {
return ERROR_INVALID_ARGUMENT;
}
switch (params.data[0]) {
2020-05-08 12:24:36 -07:00
case TEST_VERIFY_TRANSLATIONS: {
2020-04-28 14:33:56 -07:00
sol_log("verify data translations");
static const int ARGUMENT_INDEX = 0;
static const int INVOKED_ARGUMENT_INDEX = 1;
static const int INVOKED_PROGRAM_INDEX = 2;
static const int INVOKED_PROGRAM_DUP_INDEX = 3;
sol_assert(sol_deserialize(input, &params, 4));
SolPubkey bpf_loader_id =
(SolPubkey){.x = {2, 168, 246, 145, 78, 136, 161, 110, 57, 90, 225,
40, 148, 143, 250, 105, 86, 147, 55, 104, 24, 221,
71, 67, 82, 33, 243, 198, 0, 0, 0, 0}};
SolPubkey bpf_loader_deprecated_id =
2020-04-28 14:33:56 -07:00
(SolPubkey){.x = {2, 168, 246, 145, 78, 136, 161, 107, 189, 35, 149,
133, 95, 100, 4, 217, 180, 244, 86, 183, 130, 27,
176, 20, 87, 73, 66, 140, 0, 0, 0, 0}};
for (int i = 0; i < params.data_len; i++) {
sol_assert(params.data[i] == i);
}
sol_assert(params.ka_num == 4);
sol_assert(*accounts[ARGUMENT_INDEX].lamports == 42);
sol_assert(accounts[ARGUMENT_INDEX].data_len == 100);
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
sol_assert(accounts[ARGUMENT_INDEX].is_writable);
sol_assert(accounts[ARGUMENT_INDEX].rent_epoch == 0);
2020-04-28 14:33:56 -07:00
sol_assert(!accounts[ARGUMENT_INDEX].executable);
for (int i = 0; i < accounts[ARGUMENT_INDEX].data_len; i++) {
sol_assert(accounts[ARGUMENT_INDEX].data[i] == i);
}
sol_assert(SolPubkey_same(accounts[INVOKED_ARGUMENT_INDEX].owner,
accounts[INVOKED_PROGRAM_INDEX].key));
sol_assert(*accounts[INVOKED_ARGUMENT_INDEX].lamports == 10);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].data_len == 10);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_signer);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_writable);
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].rent_epoch == 0);
2020-04-28 14:33:56 -07:00
sol_assert(!accounts[INVOKED_ARGUMENT_INDEX].executable);
sol_assert(
SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].key, params.program_id))
sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].owner,
2020-05-08 12:24:36 -07:00
&bpf_loader_id));
2020-04-28 14:33:56 -07:00
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_signer);
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_writable);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch == 0);
2020-04-28 14:33:56 -07:00
sol_assert(accounts[INVOKED_PROGRAM_INDEX].executable);
sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].key,
accounts[INVOKED_PROGRAM_DUP_INDEX].key));
sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].owner,
accounts[INVOKED_PROGRAM_DUP_INDEX].owner));
sol_assert(*accounts[INVOKED_PROGRAM_INDEX].lamports ==
*accounts[INVOKED_PROGRAM_DUP_INDEX].lamports);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].is_signer ==
accounts[INVOKED_PROGRAM_DUP_INDEX].is_signer);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].is_writable ==
accounts[INVOKED_PROGRAM_DUP_INDEX].is_writable);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch ==
accounts[INVOKED_PROGRAM_DUP_INDEX].rent_epoch);
sol_assert(accounts[INVOKED_PROGRAM_INDEX].executable ==
accounts[INVOKED_PROGRAM_DUP_INDEX].executable);
break;
}
2020-05-08 12:24:36 -07:00
case TEST_RETURN_ERROR: {
sol_log("return error");
2020-04-28 14:33:56 -07:00
return 42;
}
2020-05-08 12:24:36 -07:00
case TEST_DERIVED_SIGNERS: {
2020-04-28 14:33:56 -07:00
sol_log("verify derived signers");
2020-05-08 12:24:36 -07:00
static const int INVOKED_PROGRAM_INDEX = 0;
static const int DERIVED_KEY1_INDEX = 1;
static const int DERIVED_KEY2_INDEX = 2;
static const int DERIVED_KEY3_INDEX = 3;
sol_assert(sol_deserialize(input, &params, 4));
sol_assert(accounts[DERIVED_KEY1_INDEX].is_signer);
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
uint8_t nonce2 = params.data[1];
uint8_t nonce3 = params.data[2];
2020-05-08 12:24:36 -07:00
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY1_INDEX].key, true, false},
{accounts[DERIVED_KEY2_INDEX].key, true, true},
{accounts[DERIVED_KEY3_INDEX].key, false, true}};
uint8_t data[] = {TEST_VERIFY_NESTED_SIGNERS};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
uint8_t seed1[] = {'L', 'i', 'l', '\''};
uint8_t seed2[] = {'B', 'i', 't', 's'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{seed2, SOL_ARRAY_SIZE(seed2)},
{&nonce2, 1}};
const SolSignerSeed seeds2[] = {
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY},
{&nonce3, 1}};
2020-05-08 12:24:36 -07:00
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
{seeds2, SOL_ARRAY_SIZE(seeds2)}};
sol_assert(SUCCESS == sol_invoke_signed(
&instruction, accounts, SOL_ARRAY_SIZE(accounts),
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));
break;
}
case TEST_VERIFY_NESTED_SIGNERS: {
sol_log("verify derived nested signers");
static const int DERIVED_KEY1_INDEX = 0;
2020-04-28 14:33:56 -07:00
static const int DERIVED_KEY2_INDEX = 1;
2020-05-08 12:24:36 -07:00
static const int DERIVED_KEY3_INDEX = 2;
sol_assert(sol_deserialize(input, &params, 3));
2020-04-28 14:33:56 -07:00
2020-05-08 12:24:36 -07:00
sol_assert(!accounts[DERIVED_KEY1_INDEX].is_signer);
sol_assert(accounts[DERIVED_KEY2_INDEX].is_signer);
2020-04-28 14:33:56 -07:00
sol_assert(accounts[DERIVED_KEY2_INDEX].is_signer);
break;
}
2020-05-08 12:24:36 -07:00
case TEST_VERIFY_WRITER: {
2020-04-28 14:33:56 -07:00
sol_log("verify writable");
static const int ARGUMENT_INDEX = 0;
sol_assert(sol_deserialize(input, &params, 1));
sol_assert(accounts[ARGUMENT_INDEX].is_writable);
break;
}
case TEST_VERIFY_PRIVILEGE_ESCALATION: {
sol_log("Success");
}
2020-05-08 12:24:36 -07:00
case TEST_NESTED_INVOKE: {
2020-04-28 14:33:56 -07:00
sol_log("invoke");
static const int INVOKED_ARGUMENT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
2020-05-08 12:24:36 -07:00
sol_assert(sol_deserialize(input, &params, 2));
2020-04-28 14:33:56 -07:00
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_signer);
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
*accounts[INVOKED_ARGUMENT_INDEX].lamports -= 1;
*accounts[ARGUMENT_INDEX].lamports += 1;
sol_log("Last invoke");
for (int i = 0; i < accounts[INVOKED_ARGUMENT_INDEX].data_len; i++) {
accounts[INVOKED_ARGUMENT_INDEX].data[i] = i;
}
break;
}
default:
return ERROR_INVALID_INSTRUCTION_DATA;
}
return SUCCESS;
}