Program Listing for File test_block.cu#
↰ Return to documentation for file (src/test/test_block.cu
)
// cuEVM: CUDA Ethereum Virtual Machine implementation
// Copyright 2023 Stefan-Dan Ciocirlan (SBIP - Singapore Blockchain Innovation Programme)
// Author: Stefan-Dan Ciocirlan
// Data: 2023-11-30
// SPDX-License-Identifier: MIT
#include "../utils.h"
#include "../block.cuh"
template <class params>
__host__ __device__ __forceinline__ void test_block(
arith_env_t<params> &arith,
typename block_t<params>::block_data_t *current_block_data,
uint32_t &instance)
{
typedef block_t<params> block_t;
typedef arith_env_t<params> arith_t;
typedef typename arith_t::bn_t bn_t;
// get the current block
block_t *block;
block = new block_t(arith, current_block_data);
bn_t a, b;
// current block
block->get_coin_base(a);
printf("coin_base: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_difficulty(a);
printf("difficulty: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_gas_limit(a);
printf("gas_limit: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_number(a);
printf("number: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_time_stamp(a);
printf("time_stamp: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_chain_id(a);
printf("chain_id: %08x\n", cgbn_get_ui32(arith._env, a));
block->get_base_fee(a);
printf("base_fee: %08x\n", cgbn_get_ui32(arith._env, a));
// block hash
cgbn_set_ui32(arith._env, b, 0);
uint32_t error_code = 0;
block->get_previous_hash(a, b, error_code);
printf("previous hash %08x for number %08x, with error %d\n", cgbn_get_ui32(arith._env, a), cgbn_get_ui32(arith._env, b), error_code);
// block->print();
delete block;
block = NULL;
printf("Block deleted\n");
}
template <class params>
__global__ void kernel_block(
cgbn_error_report_t *report,
typename block_t<params>::block_data_t *current_block_data)
{
uint32_t instance = (blockIdx.x * blockDim.x + threadIdx.x) / params::TPI;
typedef arith_env_t<params> arith_t;
arith_t arith(cgbn_report_monitor, report, instance);
printf("kernel %p\n", current_block_data);
test_block(arith, current_block_data, instance);
}
void run_test()
{
#ifndef ONLY_CPU
CUDA_CHECK(cudaDeviceReset());
CUDA_CHECK(cudaDeviceSetLimit(cudaLimitMallocHeapSize, 1024*1024*1024));
CUDA_CHECK(cudaDeviceSetLimit(cudaLimitStackSize, 64*1024));
#endif
typedef block_t<utils_params> block_t;
typedef typename block_t::block_data_t block_data_t;
typedef arith_env_t<utils_params> arith_t;
block_data_t *block_data = NULL;
block_t *cpu_block = NULL;
arith_t arith(cgbn_report_monitor, 0);
// read the json file with the global state
cJSON *root = get_json_from_file("input/evm_test.json");
if (root == NULL)
{
printf("Error: could not read the json file\n");
exit(1);
}
const cJSON *test = NULL;
test = cJSON_GetObjectItemCaseSensitive(root, "mstore8");
printf("Generating the global block\n");
cpu_block = new block_t(arith, test);
block_data = cpu_block->_content;
printf("Global block generated\n");
cpu_block->print();
// create a cgbn_error_report for CGBN to report back errors
#ifndef ONLY_CPU
cgbn_error_report_t *report;
CUDA_CHECK(cgbn_error_report_alloc(&report));
printf("Running GPU kernel ...\n");
kernel_block<utils_params><<<1, utils_params::TPI>>>(report, block_data);
// error report uses managed memory, so we sync the device (or stream) and check for cgbn errors
CUDA_CHECK(cudaDeviceSynchronize());
printf("GPU kernel finished\n");
CGBN_CHECK(report);
// clean up
CUDA_CHECK(cgbn_error_report_free(report));
#else
printf("Running CPU kernel ...\n");
uint32_t instance = 0;
test_block<utils_params>(arith, block_data, instance);
printf("CPU kernel finished\n");
#endif
printf("Printing ...\n");
cpu_block->print();
printf("Printed\n");
printf("Printing to json files ...\n");
cJSON_Delete(root);
root = cJSON_CreateObject();
cJSON_AddItemToObject(root, "env", cpu_block->json());
char *json_str = cJSON_Print(root);
FILE *fp = fopen("output/evm_block.json", "w");
fprintf(fp, "%s", json_str);
fclose(fp);
free(json_str);
cJSON_Delete(root);
printf("Json files printed\n");
cpu_block->free_content();
delete cpu_block;
cpu_block = NULL;
#ifndef ONLY_CPU
CUDA_CHECK(cudaDeviceReset());
#endif
}
int main()
{
run_test();
}