Program bank integration (#1462)
Native, BPF and Lua loaders integrated into the bank
This commit is contained in:
@ -24,7 +24,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
SolPubkey *key;
|
||||
int64_t tokens;
|
||||
int64_t* tokens;
|
||||
uint64_t userdata_len;
|
||||
uint8_t *userdata;
|
||||
SolPubkey *program_id;
|
||||
@ -50,7 +50,7 @@ SOL_FN_PREFIX void _sol_panic(uint64_t line) {
|
||||
SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
uint8_t **userdata, uint64_t *userdata_len) {
|
||||
if (num_ka != *(uint64_t *)src) {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
src += sizeof(uint64_t);
|
||||
|
||||
@ -61,8 +61,8 @@ SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccount
|
||||
src += SIZE_PUBKEY;
|
||||
|
||||
// tokens
|
||||
ka[i].tokens = *(uint64_t *)src;
|
||||
src += sizeof(uint64_t);
|
||||
ka[i].tokens = (int64_t *)src;
|
||||
src += sizeof(int64_t);
|
||||
|
||||
// account userdata
|
||||
ka[i].userdata_len = *(uint64_t *)src;
|
||||
@ -79,7 +79,7 @@ SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccount
|
||||
src += sizeof(uint64_t);
|
||||
*userdata = src;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ SOL_FN_PREFIX void print_params(uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
print_key(ka[i].key);
|
||||
|
||||
// tokens
|
||||
sol_print(0, 0, 0, 0, ka[i].tokens);
|
||||
sol_print(0, 0, 0, 0, *ka[i].tokens);
|
||||
|
||||
// account userdata
|
||||
print_userdata(ka[i].userdata, ka[i].userdata_len);
|
||||
@ -117,14 +117,24 @@ SOL_FN_PREFIX void print_params(uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
print_userdata(userdata, userdata_len);
|
||||
}
|
||||
|
||||
void entrypoint(char *buf) {
|
||||
uint64_t entrypoint(char *buf) {
|
||||
SolKeyedAccounts ka[3];
|
||||
uint64_t userdata_len;
|
||||
uint8_t *userdata;
|
||||
|
||||
if (0 != sol_deserialize((uint8_t *)buf, 3, ka, &userdata, &userdata_len)) {
|
||||
return;
|
||||
if (1 != sol_deserialize((uint8_t *)buf, 3, ka, &userdata, &userdata_len)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_params(3, ka, userdata, userdata_len);
|
||||
|
||||
int64_t tokens = *(int64_t*)userdata;
|
||||
if (*ka[0].tokens >= tokens) {
|
||||
*ka[0].tokens -= tokens;
|
||||
*ka[2].tokens += tokens;
|
||||
//sol_print(0, 0, *ka[0].tokens, *ka[2].tokens, tokens);
|
||||
} else {
|
||||
//sol_print(0, 0, 0xFF, *ka[0].tokens, tokens);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
9
programs/bpf/noop_c/build.sh
Executable file
9
programs/bpf/noop_c/build.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
OUTDIR="${1:-../../../target/release/}"
|
||||
THISDIR=$(dirname "$0")
|
||||
mkdir -p "$OUTDIR"
|
||||
/usr/local/opt/llvm/bin/clang -Werror -target bpf -O2 -emit-llvm -fno-builtin -o "$OUTDIR"/noop_c.bc -c "$THISDIR"/src/noop.c
|
||||
/usr/local/opt/llvm/bin/llc -march=bpf -filetype=obj -function-sections -o "$OUTDIR"/noop_c.o "$OUTDIR"/noop_c.bc
|
||||
|
||||
#/usr/local/opt/llvm/bin/llvm-objdump -color -source -disassemble "$OUTDIR"/noop_c.o
|
3
programs/bpf/noop_c/dump.sh
Executable file
3
programs/bpf/noop_c/dump.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
/usr/local/opt/llvm/bin/llvm-objdump -color -source -disassemble ../../../target/release/noop_c.o
|
133
programs/bpf/noop_c/src/noop.c
Normal file
133
programs/bpf/noop_c/src/noop.c
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
//#include <stdint.h>
|
||||
//#include <stddef.h>
|
||||
|
||||
#if 1
|
||||
// one way to define a helper function is with index as a fixed value
|
||||
#define BPF_TRACE_PRINTK_IDX 6
|
||||
static int (*sol_print)(int, int, int, int, int) = (void *)BPF_TRACE_PRINTK_IDX;
|
||||
#else
|
||||
// relocation is another option
|
||||
extern int sol_print(int, int, int, int, int);
|
||||
#endif
|
||||
|
||||
typedef long long unsigned int uint64_t;
|
||||
typedef long long int int64_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef enum { false = 0, true } bool;
|
||||
|
||||
#define SIZE_PUBKEY 32
|
||||
typedef struct {
|
||||
uint8_t x[SIZE_PUBKEY];
|
||||
} SolPubkey;
|
||||
|
||||
typedef struct {
|
||||
SolPubkey *key;
|
||||
int64_t* tokens;
|
||||
uint64_t userdata_len;
|
||||
uint8_t *userdata;
|
||||
SolPubkey *program_id;
|
||||
} SolKeyedAccounts;
|
||||
|
||||
// TODO support BPF function calls rather then forcing everything to be inlined
|
||||
#define SOL_FN_PREFIX __attribute__((always_inline)) static
|
||||
|
||||
// TODO move this to a registered helper
|
||||
SOL_FN_PREFIX void sol_memcpy(void *dst, void *src, int len) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
*((uint8_t *)dst + i) = *((uint8_t *)src + i);
|
||||
}
|
||||
}
|
||||
|
||||
#define sol_panic() _sol_panic(__LINE__)
|
||||
SOL_FN_PREFIX void _sol_panic(uint64_t line) {
|
||||
sol_print(0, 0, 0xFF, 0xFF, line);
|
||||
char *pv = (char *)1;
|
||||
*pv = 1;
|
||||
}
|
||||
|
||||
SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
uint8_t **userdata, uint64_t *userdata_len) {
|
||||
if (num_ka != *(uint64_t *)src) {
|
||||
return 0;
|
||||
}
|
||||
src += sizeof(uint64_t);
|
||||
|
||||
// TODO fixed iteration loops ok? unrolled?
|
||||
for (int i = 0; i < num_ka; i++) { // TODO this should end up unrolled, confirm
|
||||
// key
|
||||
ka[i].key = (SolPubkey *)src;
|
||||
src += SIZE_PUBKEY;
|
||||
|
||||
// tokens
|
||||
ka[i].tokens = (int64_t *)src;
|
||||
src += sizeof(int64_t);
|
||||
|
||||
// account userdata
|
||||
ka[i].userdata_len = *(uint64_t *)src;
|
||||
src += sizeof(uint64_t);
|
||||
ka[i].userdata = src;
|
||||
src += ka[i].userdata_len;
|
||||
|
||||
// program_id
|
||||
ka[i].program_id = (SolPubkey *)src;
|
||||
src += SIZE_PUBKEY;
|
||||
}
|
||||
// tx userdata
|
||||
*userdata_len = *(uint64_t *)src;
|
||||
src += sizeof(uint64_t);
|
||||
*userdata = src;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// -- Debug --
|
||||
|
||||
SOL_FN_PREFIX void print_key(SolPubkey *key) {
|
||||
for (int j = 0; j < SIZE_PUBKEY; j++) {
|
||||
sol_print(0, 0, 0, j, key->x[j]);
|
||||
}
|
||||
}
|
||||
|
||||
SOL_FN_PREFIX void print_userdata(uint8_t *data, int len) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
sol_print(0, 0, 0, j, data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
SOL_FN_PREFIX void print_params(uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
uint8_t *userdata, uint64_t userdata_len) {
|
||||
sol_print(0, 0, 0, 0, num_ka);
|
||||
for (int i = 0; i < num_ka; i++) {
|
||||
// key
|
||||
print_key(ka[i].key);
|
||||
|
||||
// tokens
|
||||
sol_print(0, 0, 0, 0, *ka[i].tokens);
|
||||
|
||||
// account userdata
|
||||
print_userdata(ka[i].userdata, ka[i].userdata_len);
|
||||
|
||||
// program_id
|
||||
print_key(ka[i].program_id);
|
||||
}
|
||||
// tx userdata
|
||||
print_userdata(userdata, userdata_len);
|
||||
}
|
||||
|
||||
// -- Program entrypoint --
|
||||
|
||||
uint64_t entrypoint(char *buf) {
|
||||
SolKeyedAccounts ka[1];
|
||||
uint64_t userdata_len;
|
||||
uint8_t *userdata;
|
||||
|
||||
if (1 != sol_deserialize((uint8_t *)buf, 1, ka, &userdata, &userdata_len)) {
|
||||
return 0;
|
||||
}
|
||||
print_params(1, ka, userdata, userdata_len);
|
||||
return 1;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ SOL_FN_PREFIX void _sol_panic(uint64_t line) {
|
||||
SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
uint8_t **userdata, uint64_t *userdata_len) {
|
||||
if (num_ka != *(uint64_t *)src) {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
src += sizeof(uint64_t);
|
||||
|
||||
@ -78,9 +78,55 @@ SOL_FN_PREFIX int sol_deserialize(uint8_t *src, uint64_t num_ka, SolKeyedAccount
|
||||
src += sizeof(uint64_t);
|
||||
*userdata = src;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// // -- Debug --
|
||||
|
||||
SOL_FN_PREFIX void print_key(SolPubkey *key) {
|
||||
for (int j = 0; j < SIZE_PUBKEY; j++) {
|
||||
sol_print(0, 0, 0, j, key->x[j]);
|
||||
}
|
||||
}
|
||||
|
||||
SOL_FN_PREFIX void print_userdata(uint8_t *data, int len) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
sol_print(0, 0, 0, j, data[j]);
|
||||
}
|
||||
}
|
||||
|
||||
SOL_FN_PREFIX void print_params(uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
uint8_t *userdata, uint64_t userdata_len) {
|
||||
sol_print(0, 0, 0, 0, num_ka);
|
||||
for (int i = 0; i < num_ka; i++) {
|
||||
// key
|
||||
print_key(ka[i].key);
|
||||
|
||||
// tokens
|
||||
sol_print(0, 0, 0, 0, ka[i].tokens);
|
||||
|
||||
// account userdata
|
||||
print_userdata(ka[i].userdata, ka[i].userdata_len);
|
||||
|
||||
// program_id
|
||||
print_key(ka[i].program_id);
|
||||
}
|
||||
// tx userdata
|
||||
print_userdata(userdata, userdata_len);
|
||||
}
|
||||
|
||||
// void entrypoint(char *buf) {
|
||||
// SolKeyedAccounts ka[3];
|
||||
// uint64_t userdata_len;
|
||||
// uint8_t *userdata;
|
||||
|
||||
// if (0 != sol_deserialize((uint8_t *)buf, 3, ka, &userdata, &userdata_len)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// print_params(3, ka, userdata, userdata_len);
|
||||
// }
|
||||
|
||||
// -- TicTacToe --
|
||||
|
||||
// Board Coodinates
|
||||
@ -279,92 +325,48 @@ SOL_FN_PREFIX Result game_keep_alive(Game *self, SolPubkey *player,
|
||||
return Result_Ok;
|
||||
}
|
||||
|
||||
void entrypoint(uint8_t *buf) {
|
||||
SolKeyedAccounts ka[3];
|
||||
uint64_t entrypoint(uint8_t *buf) {
|
||||
SolKeyedAccounts ka[4];
|
||||
uint64_t userdata_len;
|
||||
uint8_t *userdata;
|
||||
int err = 0;
|
||||
|
||||
if (0 != sol_deserialize(buf, 3, ka, &userdata, &userdata_len)) {
|
||||
sol_panic();
|
||||
if (1 != sol_deserialize(buf, 4, ka, &userdata, &userdata_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sizeof(Game) > ka[1].userdata_len) {
|
||||
sol_print(0, 0, 0xFF, sizeof(Game), ka[1].userdata_len);
|
||||
sol_panic();
|
||||
if (sizeof(Game) > ka[2].userdata_len) {
|
||||
sol_print(0, 0, 0xFF, sizeof(Game), ka[2].userdata_len);
|
||||
return 0;
|
||||
}
|
||||
Game game;
|
||||
sol_memcpy(&game, ka[1].userdata, ka[1].userdata_len);
|
||||
sol_memcpy(&game, ka[2].userdata, ka[2].userdata_len);
|
||||
|
||||
Command command = *userdata;
|
||||
sol_print(0, 0, 0, 0, command);
|
||||
//sol_print(0, 0, 0, 0, command);
|
||||
switch (command) {
|
||||
case Command_Init:
|
||||
game_create(&game, ka[2].key);
|
||||
game_create(&game, ka[3].key);
|
||||
break;
|
||||
|
||||
case Command_Join:
|
||||
err = game_join(&game, ka[0].key, userdata[8]);
|
||||
err = game_join(&game, ka[3].key, userdata[8]);
|
||||
break;
|
||||
|
||||
case Command_KeepAlive:
|
||||
err = game_keep_alive(&game, ka[0].key, /*TODO*/ 0);
|
||||
err = game_keep_alive(&game, ka[3].key, /*TODO*/ 0);
|
||||
break;
|
||||
|
||||
case Command_Move:
|
||||
err = game_next_move(&game, ka[0].key, userdata[8], userdata[9]);
|
||||
err = game_next_move(&game, ka[3].key, userdata[8], userdata[9]);
|
||||
break;
|
||||
|
||||
default:
|
||||
sol_panic();
|
||||
return 0;
|
||||
}
|
||||
|
||||
sol_memcpy(ka[1].userdata, &game, ka[1].userdata_len);
|
||||
sol_memcpy(ka[2].userdata, &game, ka[2].userdata_len);
|
||||
sol_print(0, 0, 0, err, game.state);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// // -- Debug --
|
||||
|
||||
// SOL_FN_PREFIX void print_key(SolPubkey *key) {
|
||||
// for (int j = 0; j < SIZE_PUBKEY; j++) {
|
||||
// sol_print(0, 0, 0, j, key->x[j]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// SOL_FN_PREFIX void print_userdata(uint8_t *data, int len) {
|
||||
// for (int j = 0; j < len; j++) {
|
||||
// sol_print(0, 0, 0, j, data[j]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// SOL_FN_PREFIX void print_params(uint64_t num_ka, SolKeyedAccounts *ka,
|
||||
// uint8_t *userdata, uint64_t userdata_len) {
|
||||
// sol_print(0, 0, 0, 0, num_ka);
|
||||
// for (int i = 0; i < num_ka; i++) {
|
||||
// // key
|
||||
// print_key(ka[i].key);
|
||||
|
||||
// // tokens
|
||||
// sol_print(0, 0, 0, 0, ka[i].tokens);
|
||||
|
||||
// // account userdata
|
||||
// print_userdata(ka[i].userdata, ka[i].userdata_len);
|
||||
|
||||
// // program_id
|
||||
// print_key(ka[i].program_id);
|
||||
// }
|
||||
// // tx userdata
|
||||
// print_userdata(userdata, userdata_len);
|
||||
// }
|
||||
|
||||
// void entrypoint(char *buf) {
|
||||
// SolKeyedAccounts ka[3];
|
||||
// uint64_t userdata_len;
|
||||
// uint8_t *userdata;
|
||||
|
||||
// if (0 != sol_deserialize((uint8_t *)buf, 3, ka, &userdata_len, &userdata)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// print_params(3, ka, userdata, userdata_len);
|
||||
// }
|
||||
|
Reference in New Issue
Block a user