Add support for idiomatic error handling to BPF instruction processors (#7968)
This commit is contained in:
@@ -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);
|
||||
|
@@ -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, ¶ms, 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;
|
||||
}
|
||||
|
37
programs/bpf/c/src/error_handling/error_handling.c
Normal file
37
programs/bpf/c/src/error_handling/error_handling.c
Normal 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, ¶ms, 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;
|
||||
}
|
@@ -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, ¶ms, 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;
|
||||
|
@@ -16,7 +16,7 @@ extern uint32_t entrypoint(const uint8_t *input) {
|
||||
sol_log(__FILE__);
|
||||
|
||||
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||
return INVALID_INPUT;
|
||||
return INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// Log the provided input parameters. In the case of the no-op
|
||||
|
@@ -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, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||
return INVALID_INPUT;
|
||||
return INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
// Log the provided input parameters. In the case of the no-op
|
||||
|
Reference in New Issue
Block a user