Programs can only sign their accounts
This commit is contained in:
@ -1,22 +1,23 @@
|
||||
/**
|
||||
* @brief Example C-based BPF program that prints out the parameters
|
||||
* passed to it
|
||||
* @brief Example C-based BPF program that tests cross-program invocations
|
||||
*/
|
||||
#include "../invoked/instruction.h"
|
||||
#include <solana_sdk.h>
|
||||
|
||||
#define MINT_INDEX 0
|
||||
#define ARGUMENT_INDEX 1
|
||||
#define INVOKED_PROGRAM_INDEX 2
|
||||
#define INVOKED_ARGUMENT_INDEX 3
|
||||
#define INVOKED_PROGRAM_DUP_INDEX 4
|
||||
#define ARGUMENT_DUP_INDEX 5
|
||||
#define DERIVED_KEY_INDEX 6
|
||||
#define DERIVED_KEY2_INDEX 7
|
||||
static const int MINT_INDEX = 0;
|
||||
static const int ARGUMENT_INDEX = 1;
|
||||
static const int INVOKED_PROGRAM_INDEX = 2;
|
||||
static const int INVOKED_ARGUMENT_INDEX = 3;
|
||||
static const int INVOKED_PROGRAM_DUP_INDEX = 4;
|
||||
static const int ARGUMENT_DUP_INDEX = 5;
|
||||
static const int DERIVED_KEY1_INDEX = 6;
|
||||
static const int DERIVED_KEY2_INDEX = 7;
|
||||
static const int DERIVED_KEY3_INDEX = 8;
|
||||
|
||||
extern uint64_t entrypoint(const uint8_t *input) {
|
||||
sol_log("Invoke C program");
|
||||
|
||||
SolAccountInfo accounts[8];
|
||||
SolAccountInfo accounts[9];
|
||||
SolParameters params = (SolParameters){.ka = accounts};
|
||||
|
||||
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(accounts))) {
|
||||
@ -34,40 +35,45 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
{accounts[INVOKED_ARGUMENT_INDEX].key, true, true},
|
||||
{accounts[INVOKED_PROGRAM_INDEX].key, false, false},
|
||||
{accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false}};
|
||||
uint8_t data[] = {0, 1, 2, 3, 4, 5};
|
||||
uint8_t data[] = {TEST_VERIFY_TRANSLATIONS, 1, 2, 3, 4, 5};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, 4, data, 6};
|
||||
|
||||
sol_assert(SUCCESS == sol_invoke(&instruction, accounts,
|
||||
SOL_ARRAY_SIZE(accounts)));
|
||||
sol_assert(SUCCESS ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
}
|
||||
|
||||
sol_log("Test return error");
|
||||
{
|
||||
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, true, true}};
|
||||
uint8_t data[] = {1};
|
||||
uint8_t data[] = {TEST_RETURN_ERROR};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
|
||||
sol_assert(42 == sol_invoke(&instruction, accounts,
|
||||
SOL_ARRAY_SIZE(accounts)));
|
||||
sol_assert(42 ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
}
|
||||
|
||||
sol_log("Test derived signers");
|
||||
{
|
||||
sol_assert(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY3_INDEX].is_signer);
|
||||
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[DERIVED_KEY_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY2_INDEX].key, false, true}};
|
||||
uint8_t data[] = {2};
|
||||
{accounts[INVOKED_PROGRAM_INDEX].key, false, false},
|
||||
{accounts[DERIVED_KEY1_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY2_INDEX].key, true, false},
|
||||
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
|
||||
uint8_t data[] = {TEST_DERIVED_SIGNERS};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
const SolSignerSeed seeds1[] = {{"Lil'", 4}, {"Bits", 4}};
|
||||
const SolSignerSeed seeds2[] = {{"Gar Ma Nar Nar", 14}};
|
||||
const SolSignerSeed seeds1[] = {{"You pass butter", 15}};
|
||||
const SolSignerSeed seeds2[] = {{"Lil'", 4}, {"Bits", 4}};
|
||||
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)));
|
||||
@ -77,43 +83,36 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
{
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[INVOKED_ARGUMENT_INDEX].key, true, false}};
|
||||
uint8_t data[] = {3};
|
||||
uint8_t data[] = {TEST_VERIFY_WRITER};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
|
||||
sol_assert(SUCCESS == sol_invoke(&instruction, accounts,
|
||||
SOL_ARRAY_SIZE(accounts)));
|
||||
sol_assert(SUCCESS ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
}
|
||||
|
||||
sol_log("Test invoke");
|
||||
{
|
||||
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
|
||||
*accounts[ARGUMENT_INDEX].lamports -= 5;
|
||||
*accounts[INVOKED_ARGUMENT_INDEX].lamports += 5;
|
||||
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[INVOKED_ARGUMENT_INDEX].key, true, true},
|
||||
{accounts[ARGUMENT_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY_INDEX].key, true, true}};
|
||||
uint8_t data[] = {4};
|
||||
{accounts[ARGUMENT_INDEX].key, true, true}};
|
||||
uint8_t data[] = {TEST_NESTED_INVOKE};
|
||||
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
const SolSignerSeed seeds[] = {{"Lil'", 4}, {"Bits", 4}};
|
||||
const SolSignerSeeds signers_seeds[] = {{seeds, SOL_ARRAY_SIZE(seeds)}};
|
||||
|
||||
sol_log("Fist invoke");
|
||||
sol_assert(SUCCESS == sol_invoke_signed(
|
||||
&instruction, accounts, SOL_ARRAY_SIZE(accounts),
|
||||
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));
|
||||
sol_assert(SUCCESS ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
sol_log("2nd invoke from first program");
|
||||
sol_assert(SUCCESS == sol_invoke_signed(
|
||||
&instruction, accounts, SOL_ARRAY_SIZE(accounts),
|
||||
signers_seeds, SOL_ARRAY_SIZE(signers_seeds)));
|
||||
sol_assert(SUCCESS ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
|
||||
sol_assert(*accounts[ARGUMENT_INDEX].lamports == 42 - 5 + 1 + 1);
|
||||
sol_assert(*accounts[INVOKED_ARGUMENT_INDEX].lamports == 10 + 5 - 1 - 1);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Example C-based BPF program that prints out the parameters
|
||||
* passed to it
|
||||
* @brief Example C-based BPF program that tests cross-program invocations
|
||||
*/
|
||||
#include "instruction.h"
|
||||
#include <solana_sdk.h>
|
||||
|
||||
extern uint64_t entrypoint(const uint8_t *input) {
|
||||
@ -13,7 +13,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
}
|
||||
|
||||
switch (params.data[0]) {
|
||||
case (0): {
|
||||
case TEST_VERIFY_TRANSLATIONS: {
|
||||
sol_log("verify data translations");
|
||||
|
||||
static const int ARGUMENT_INDEX = 0;
|
||||
@ -54,7 +54,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
sol_assert(
|
||||
SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].key, params.program_id))
|
||||
sol_assert(SolPubkey_same(accounts[INVOKED_PROGRAM_INDEX].owner,
|
||||
&bpf_loader_id));
|
||||
&bpf_loader_id));
|
||||
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_signer);
|
||||
sol_assert(!accounts[INVOKED_PROGRAM_INDEX].is_writable);
|
||||
sol_assert(accounts[INVOKED_PROGRAM_INDEX].rent_epoch == 1);
|
||||
@ -76,21 +76,55 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
accounts[INVOKED_PROGRAM_DUP_INDEX].executable);
|
||||
break;
|
||||
}
|
||||
case (1): {
|
||||
case TEST_RETURN_ERROR: {
|
||||
sol_log("reutrn error");
|
||||
return 42;
|
||||
}
|
||||
case (2): {
|
||||
case TEST_DERIVED_SIGNERS: {
|
||||
sol_log("verify derived signers");
|
||||
static const int DERIVED_KEY_INDEX = 0;
|
||||
static const int DERIVED_KEY2_INDEX = 1;
|
||||
sol_assert(sol_deserialize(input, ¶ms, 2));
|
||||
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, ¶ms, 4));
|
||||
|
||||
sol_assert(accounts[DERIVED_KEY_INDEX].is_signer);
|
||||
sol_assert(accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
|
||||
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)};
|
||||
const SolSignerSeed seeds1[] = {{"Lil'", 4}, {"Bits", 4}};
|
||||
const SolSignerSeed seeds2[] = {{"Gar Ma Nar Nar", 14}};
|
||||
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;
|
||||
static const int DERIVED_KEY2_INDEX = 1;
|
||||
static const int DERIVED_KEY3_INDEX = 2;
|
||||
sol_assert(sol_deserialize(input, ¶ms, 3));
|
||||
|
||||
sol_assert(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||
sol_assert(accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
sol_assert(accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||
break;
|
||||
}
|
||||
case (3): {
|
||||
|
||||
case TEST_VERIFY_WRITER: {
|
||||
sol_log("verify writable");
|
||||
static const int ARGUMENT_INDEX = 0;
|
||||
sol_assert(sol_deserialize(input, ¶ms, 1));
|
||||
@ -98,17 +132,15 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
sol_assert(accounts[ARGUMENT_INDEX].is_writable);
|
||||
break;
|
||||
}
|
||||
case (4): {
|
||||
case TEST_NESTED_INVOKE: {
|
||||
sol_log("invoke");
|
||||
|
||||
static const int INVOKED_ARGUMENT_INDEX = 0;
|
||||
static const int ARGUMENT_INDEX = 1;
|
||||
static const int DERIVED_KEY_INDEX = 2;
|
||||
sol_assert(sol_deserialize(input, ¶ms, 3));
|
||||
sol_assert(sol_deserialize(input, ¶ms, 2));
|
||||
|
||||
sol_assert(accounts[INVOKED_ARGUMENT_INDEX].is_signer);
|
||||
sol_assert(accounts[ARGUMENT_INDEX].is_signer);
|
||||
sol_assert(accounts[DERIVED_KEY_INDEX].is_signer);
|
||||
|
||||
*accounts[INVOKED_ARGUMENT_INDEX].lamports -= 1;
|
||||
*accounts[ARGUMENT_INDEX].lamports += 1;
|
||||
|
Reference in New Issue
Block a user