Add support for idiomatic error handling to BPF instruction processors (#7968)

This commit is contained in:
Jack May
2020-01-30 09:47:22 -08:00
committed by GitHub
parent 0c55b37976
commit dd276138c2
25 changed files with 515 additions and 108 deletions

View File

@@ -4,7 +4,7 @@
Test(bench_alu, sanity) {
uint64_t input[] = {500, 0};
cr_assert_eq(entrypoint((uint8_t *) input), 0);
cr_assert_eq(entrypoint((uint8_t *) input), SUCCESS);
cr_assert_eq(input[0], 500);
cr_assert_eq(input[1], 5);

View File

@@ -9,49 +9,46 @@
*/
extern uint32_t entrypoint(const uint8_t *input) {
#define FAILURE 1
#define INVALID_INPUT 2
SolKeyedAccount ka[4];
SolParameters params = (SolParameters) { .ka = ka };
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return INVALID_INPUT;
return INVALID_ARGUMENT;
}
switch (params.data[0]) {
case(1):
sol_log("modify first account userdata");
ka[2].userdata[0] = 1;
break;
case(2):
sol_log("modify first account userdata");
ka[3].userdata[0] = 2;
break;
case(3):
sol_log("modify both account userdata");
ka[2].userdata[0] += 1;
ka[3].userdata[0] += 2;
break;
case(4):
sol_log("modify first account lamports");
*ka[1].lamports -= 1;
*ka[2].lamports += 1;
break;
case(5):
sol_log("modify first account lamports");
*ka[1].lamports -= 2;
*ka[3].lamports += 2;
break;
case(6):
sol_log("modify both account lamports");
*ka[1].lamports -= 3;
*ka[2].lamports += 1;
*ka[3].lamports += 2;
break;
default:
sol_log("Unrecognized command");
return FAILURE;
case(1):
sol_log("modify first account userdata");
ka[2].userdata[0] = 1;
break;
case(2):
sol_log("modify first account userdata");
ka[3].userdata[0] = 2;
break;
case(3):
sol_log("modify both account userdata");
ka[2].userdata[0] += 1;
ka[3].userdata[0] += 2;
break;
case(4):
sol_log("modify first account lamports");
*ka[1].lamports -= 1;
*ka[2].lamports += 1;
break;
case(5):
sol_log("modify first account lamports");
*ka[1].lamports -= 2;
*ka[3].lamports += 2;
break;
case(6):
sol_log("modify both account lamports");
*ka[1].lamports -= 3;
*ka[2].lamports += 1;
*ka[3].lamports += 2;
break;
default:
sol_log("Unrecognized command");
return INVALID_INSTRUCTION_DATA;
}
return SUCCESS;
}

View File

@@ -0,0 +1,37 @@
/**
* @brief Example C-based BPF program that exercises duplicate keyed ka
* passed to it
*/
#include <solana_sdk.h>
/**
* Custom error for when input serialization fails
*/
extern uint32_t entrypoint(const uint8_t *input) {
SolKeyedAccount ka[4];
SolParameters params = (SolParameters) { .ka = ka };
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return INVALID_ARGUMENT;
}
switch (params.data[0]) {
case(1):
sol_log("return success");
return SUCCESS;
case(2):
sol_log("return a builtin");
return INVALID_ACCOUNT_DATA;
case(3):
sol_log("return custom error");
return 42;
case(4):
sol_log("return error that conflicts with success");
return 0x40000000;
default:
sol_log("Unrecognized command");
return INVALID_INSTRUCTION_DATA;
}
return SUCCESS;
}

View File

@@ -11,27 +11,17 @@
*/
#define NUM_KA 3
/**
* Custom error for when input serialization fails
*/
#define INVALID_INPUT 1
/**
* Custom error for when transaction is not signed properly
*/
#define NOT_SIGNED 2
extern uint32_t entrypoint(const uint8_t *input) {
SolKeyedAccount ka[NUM_KA];
SolParameters params = (SolParameters) { .ka = ka };
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return INVALID_INPUT;
return INVALID_ARGUMENT;
}
if (!params.ka[0].is_signer) {
sol_log("Transaction not signed by key 0");
return NOT_SIGNED;
return MISSING_REQUIRED_SIGNATURES;
}
int64_t lamports = *(int64_t *)params.data;

View File

@@ -16,7 +16,7 @@ extern uint32_t entrypoint(const uint8_t *input) {
sol_log(__FILE__);
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return INVALID_INPUT;
return INVALID_ARGUMENT;
}
// Log the provided input parameters. In the case of the no-op

View File

@@ -4,11 +4,6 @@
*/
#include <solana_sdk.h>
/**
* Custom error for when input serialization fails
*/
#define INVALID_INPUT 1
extern uint32_t entrypoint(const uint8_t *input) {
SolKeyedAccount ka[1];
SolParameters params = (SolParameters) { .ka = ka };
@@ -16,7 +11,7 @@ extern uint32_t entrypoint(const uint8_t *input) {
sol_log(__FILE__);
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return INVALID_INPUT;
return INVALID_ARGUMENT;
}
// Log the provided input parameters. In the case of the no-op