reth_db.go 1.82 KB
Newer Older
1 2
//go:build rethdb

clabby's avatar
clabby committed
3 4 5
package sources

import (
clabby's avatar
clabby committed
6
	"encoding/json"
clabby's avatar
clabby committed
7 8
	"fmt"

clabby's avatar
clabby committed
9 10
	"unsafe"

clabby's avatar
clabby committed
11 12 13 14 15 16 17 18
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
)

/*
#cgo LDFLAGS: -L../rethdb-reader/target/release -lrethdbreader
#include <stdlib.h>
#include <stdint.h>
clabby's avatar
clabby committed
19
#include <stdbool.h>
clabby's avatar
clabby committed
20 21

typedef struct {
clabby's avatar
clabby committed
22 23
    char* data;
    size_t data_len;
clabby's avatar
clabby committed
24 25 26
    bool error;
} ReceiptsResult;

clabby's avatar
clabby committed
27 28
extern ReceiptsResult rdb_read_receipts(const uint8_t* block_hash, size_t block_hash_len, const char* db_path);
extern void rdb_free_string(char* string);
clabby's avatar
clabby committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
*/
import "C"

// FetchRethReceipts fetches the receipts for the given block hash directly from the Reth Database
// and populates the given results slice pointer with the receipts that were found.
func FetchRethReceipts(dbPath string, blockHash *common.Hash) (types.Receipts, error) {
	if blockHash == nil {
		return nil, fmt.Errorf("Must provide a block hash to fetch receipts for.")
	}

	// Convert the block hash to a C byte array and defer its deallocation
	cBlockHash := C.CBytes(blockHash[:])
	defer C.free(cBlockHash)

	// Convert the db path to a C string and defer its deallocation
	cDbPath := C.CString(dbPath)
	defer C.free(unsafe.Pointer(cDbPath))

	// Call the C function to fetch the receipts from the Reth Database
clabby's avatar
clabby committed
48
	receiptsResult := C.rdb_read_receipts((*C.uint8_t)(cBlockHash), C.size_t(len(blockHash)), cDbPath)
clabby's avatar
clabby committed
49

clabby's avatar
clabby committed
50
	if receiptsResult.error {
clabby's avatar
clabby committed
51 52 53
		return nil, fmt.Errorf("Error fetching receipts from Reth Database.")
	}

clabby's avatar
clabby committed
54 55 56
	// Free the memory allocated by the C code
	defer C.rdb_free_string(receiptsResult.data)

clabby's avatar
clabby committed
57 58 59
	// Convert the returned JSON string to Go string and parse it
	receiptsJSON := C.GoStringN(receiptsResult.data, C.int(receiptsResult.data_len))
	var receipts types.Receipts
clabby's avatar
clabby committed
60 61 62
	if err := json.Unmarshal([]byte(receiptsJSON), &receipts); err != nil {
		return nil, err
	}
clabby's avatar
clabby committed
63

clabby's avatar
clabby committed
64
	return receipts, nil
clabby's avatar
clabby committed
65
}