From d328d23faaa708f1659f09ad30c6aede4adb3a38 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 29 Oct 2018 15:41:14 -0700 Subject: [PATCH] feat: add bpf-c-noop example --- web3.js/examples/bpf-c-noop/.gitignore | 1 + web3.js/examples/bpf-c-noop/makefile | 1 + web3.js/examples/bpf-c-noop/src/noop.c | 24 +++++ web3.js/test/bin/build.sh | 4 - web3.js/test/bin/noop.c | 133 ------------------------- web3.js/test/bin/noop_c.o | Bin 1472 -> 0 bytes web3.js/test/bin/noop_c.readme.txt | 9 -- web3.js/test/bpf-loader.test.js | 2 +- web3.js/test/fixtures/noop/build.sh | 4 + web3.js/test/fixtures/noop/noop.o | Bin 0 -> 1464 bytes 10 files changed, 31 insertions(+), 147 deletions(-) create mode 100644 web3.js/examples/bpf-c-noop/.gitignore create mode 100644 web3.js/examples/bpf-c-noop/makefile create mode 100644 web3.js/examples/bpf-c-noop/src/noop.c delete mode 100755 web3.js/test/bin/build.sh delete mode 100644 web3.js/test/bin/noop.c delete mode 100644 web3.js/test/bin/noop_c.o delete mode 100644 web3.js/test/bin/noop_c.readme.txt create mode 100755 web3.js/test/fixtures/noop/build.sh create mode 100644 web3.js/test/fixtures/noop/noop.o diff --git a/web3.js/examples/bpf-c-noop/.gitignore b/web3.js/examples/bpf-c-noop/.gitignore new file mode 100644 index 0000000000..6a3417b8d9 --- /dev/null +++ b/web3.js/examples/bpf-c-noop/.gitignore @@ -0,0 +1 @@ +/out/ diff --git a/web3.js/examples/bpf-c-noop/makefile b/web3.js/examples/bpf-c-noop/makefile new file mode 100644 index 0000000000..24740ee5d5 --- /dev/null +++ b/web3.js/examples/bpf-c-noop/makefile @@ -0,0 +1 @@ +include ../../bpf-sdk/bpf.mk diff --git a/web3.js/examples/bpf-c-noop/src/noop.c b/web3.js/examples/bpf-c-noop/src/noop.c new file mode 100644 index 0000000000..d78b32454a --- /dev/null +++ b/web3.js/examples/bpf-c-noop/src/noop.c @@ -0,0 +1,24 @@ +/** + * @brief Example C-based BPF program that prints out the parameters + * passed to it + */ + +#include + +/** + * Number of SolKeyedAccounts expected. The program should bail if an + * unexpected number of accounts are passed to the program's entrypoint + */ +#define NUM_KA 1 + +extern bool entrypoint(const uint8_t *input) { + SolKeyedAccounts ka[NUM_KA]; + uint8_t *data; + uint64_t data_len; + + if (!sol_deserialize(input, NUM_KA, ka, &data, &data_len)) { + return false; + } + sol_print_params(NUM_KA, ka, data, data_len); + return true; +} diff --git a/web3.js/test/bin/build.sh b/web3.js/test/bin/build.sh deleted file mode 100755 index 0eccaee228..0000000000 --- a/web3.js/test/bin/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -ex - -/usr/local/opt/llvm/bin/clang -Werror -target bpf -O2 -emit-llvm -fno-builtin -o noop_c.bc -c noop.c -/usr/local/opt/llvm/bin/llc -march=bpf -filetype=obj -function-sections -o noop_c.o noop_c.bc diff --git a/web3.js/test/bin/noop.c b/web3.js/test/bin/noop.c deleted file mode 100644 index d01220a709..0000000000 --- a/web3.js/test/bin/noop.c +++ /dev/null @@ -1,133 +0,0 @@ - -//#include -//#include - -#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; -} - diff --git a/web3.js/test/bin/noop_c.o b/web3.js/test/bin/noop_c.o deleted file mode 100644 index a6c812d02884b4ba39294406446ca97a2adf8d43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1472 zcmbtTJ4*vW5S}E)i=ae=fTp_AN{xz-LI|QFXdyxx8;KZ1!D#eAmlT>p|AAtuUF__x zywcV(rKM#+d~|VUXZDO6V+t4UzS(c*wcqZZEv_y_BM~qo0w3@_Gc3S)*SDS3W)|Y; z={wA;0mfW(O~6aos$})4HqIpSd0d<4||(pA^4RiurbZ1Rk%O z`VQ)WslmZ~gt_jwhKp$WQmJ8_0r*m{U0z@IXY%ggW?YO5DijUyh{;_<(gjV}ALzwD z&gDE##J_Z&3^DdALMa0 z<$)2eaO&}Yq)_yZ)ZxKy5s72($jfgbs(r%M`T4QUS%w*gX@*IL35IcoOs2WUKkPw_ z{iSPg<^60}xh*;Logz-2W9Xd?t)GUZ4M}=#f5j)P=IG5d4;LraQRwAmiK~e-)u31t IPy43v1$M@a0{{R3 diff --git a/web3.js/test/bin/noop_c.readme.txt b/web3.js/test/bin/noop_c.readme.txt deleted file mode 100644 index 7836d1b2bf..0000000000 --- a/web3.js/test/bin/noop_c.readme.txt +++ /dev/null @@ -1,9 +0,0 @@ - -The Solana SDK Test Binary - -One of the functions that the SDK tests exercises is the loading and calling of Berkley Packet Filter programs (BPF). - -The test file noop_c.o is an ELF object file containing a small BPF program contained in the ELF section named ".text.entrypoint". - -The C source file for noop_c.o is noop_c.c and it can be rebuilt using the build.sh script. -The build.sh script depends on LLVM 6.0 to be installed. \ No newline at end of file diff --git a/web3.js/test/bpf-loader.test.js b/web3.js/test/bpf-loader.test.js index 7deafce3c6..23c855ab88 100644 --- a/web3.js/test/bpf-loader.test.js +++ b/web3.js/test/bpf-loader.test.js @@ -25,7 +25,7 @@ test('load BPF program', async () => { const connection = new Connection(url); const from = await newAccountWithTokens(connection); - const data = await fs.readFile('test/bin/noop_c.o'); + const data = await fs.readFile('test/fixtures/noop/noop.o'); const programId = await BpfLoader.load(connection, from, data); const transaction = new Transaction().add({ keys: [from.publicKey], diff --git a/web3.js/test/fixtures/noop/build.sh b/web3.js/test/fixtures/noop/build.sh new file mode 100755 index 0000000000..9ed8c83f50 --- /dev/null +++ b/web3.js/test/fixtures/noop/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash -ex + +make -C ../../../examples/bpf-c-noop/ +cp ../../../examples/bpf-c-noop/out/noop.o . diff --git a/web3.js/test/fixtures/noop/noop.o b/web3.js/test/fixtures/noop/noop.o new file mode 100644 index 0000000000000000000000000000000000000000..041d82bf46afa0efab273554b3ab6bc120120b0a GIT binary patch literal 1464 zcmbtTIZFdU6n<-rtDr;#MFYZ?R^E6NLJ+l4EQBW^UiN)PG%S88XO1ga^Mv{ca{Y>Zv3<}Y-S*do>7JlIXYH(TY3dRsSO!S6~|I zooB^VSRZpOI=NV!^;F%=jq0kprF^OTuYT*|XXmExL~~`EL_eB`_NFBFAS#Ie29h3{ zRu6M4edQdv7}1{ioeO}~-|ARzf4!T}tVa@F7`4ndSYjptr+Qzl!@TnMmQb8g{wn4_ zrF<#Ik12maBGs$`wi8f}@p2mz&>YLthW_oKkEtdP^ar`)K>qu4JHdh3+uhnh;xIS} z{53?gO}H>UJ-9k4Fd;B5Fe)%2Ff1@MR9mACyBlMF=o-59JuSy_$K>Fy7h~m literal 0 HcmV?d00001