Skip to content

Commit 2cfa198

Browse files
committed
feat: add Rust FFI integration for last 5 blocks fetching
1 parent 067b118 commit 2cfa198

5 files changed

Lines changed: 66 additions & 11 deletions

File tree

goCode/goApp/main.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ package main
66
77
// fetch_transactions je Rust funkcija koja vraca podatke o transakcijama iz poslednjeg bloka
88
char* fetch_transactions(const char* rpc_url);
9+
10+
// fetch_last_5_blocks je Rust funkcija koja vraca podatke o transakciji maksimalnog potrosenog gasa u poslednjih 5 blokova
11+
char* fetch_last_5_blocks(const char* rpc_url);
912
*/
1013
import "C"
1114

1215
import (
16+
"encoding/json"
1317
"fmt"
1418
"unsafe"
1519

@@ -21,28 +25,49 @@ import (
2125

2226
func main() {
2327

24-
rpcURL, recipientAddress, privateKeyHex := config.LoadEnv()
28+
rpcTestnetURL, rpcMainnetURL, recipientAddress, privateKeyHex := config.LoadEnv()
2529

26-
blockNumber := rpc.GetLatestBlock(rpcURL)
30+
blockNumber := rpc.GetLatestBlock(rpcTestnetURL)
2731
fmt.Println(blockNumber)
2832
fmt.Println()
2933

3034
fakeBalance := utilis.EthToHex(100) // 100 ETH
31-
transaction.SetFakeBalance(rpcURL, recipientAddress, fakeBalance)
35+
transaction.SetFakeBalance(rpcTestnetURL, recipientAddress, fakeBalance)
3236

3337
sendEth := 1
34-
transaction.SendTransaction(rpcURL, recipientAddress, int64(sendEth), privateKeyHex)
38+
transaction.SendTransaction(rpcTestnetURL, recipientAddress, int64(sendEth), privateKeyHex)
3539

36-
//---------------------------
40+
// === Deo koji zove Rust FFI za transakcije ===
3741
fmt.Println()
3842

39-
cRpcURL := C.CString(rpcURL)
40-
defer C.free(unsafe.Pointer(cRpcURL))
43+
cRpcTestnetURL := C.CString(rpcTestnetURL)
44+
defer C.free(unsafe.Pointer(cRpcTestnetURL))
4145

42-
result := C.fetch_transactions(cRpcURL)
46+
result := C.fetch_transactions(cRpcTestnetURL)
4347
defer C.free(unsafe.Pointer(result))
4448

4549
goResult := C.GoString(result)
4650
fmt.Println("Rust FFI: Podaci o transakcijama iz poslednjeg bloka:\n", goResult)
4751

52+
// === Deo koji zove Rust FFI za 5 blokova ===
53+
fmt.Println()
54+
55+
cRpcMainnetURL := C.CString(rpcMainnetURL)
56+
defer C.free(unsafe.Pointer(cRpcMainnetURL))
57+
58+
resultArray := C.fetch_last_5_blocks(cRpcMainnetURL)
59+
defer C.free(unsafe.Pointer(resultArray))
60+
goArray := C.GoString(resultArray)
61+
62+
var summaries []rpc.TxSummary
63+
err := json.Unmarshal([]byte(goArray), &summaries)
64+
if err != nil {
65+
fmt.Println("Greska pri parsiranju JSON-a iz Rust-a:", err)
66+
return
67+
}
68+
69+
for _, s := range summaries {
70+
fmt.Printf("Blok %s | TX %s | Gas %d | %.3f%% u bloku\n",
71+
s.BlockNumber, s.TxHash, s.GasUsed, s.PercentInBlock)
72+
}
4873
}

goCode/internal/config/config.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"github.com/joho/godotenv"
88
)
99

10-
func LoadEnv() (string, string, string) {
10+
func LoadEnv() (string, string, string, string) {
1111
err := godotenv.Load("../.env")
1212
if err != nil {
1313
log.Fatal("Greska pri ucitavanju .env fajla")
@@ -18,6 +18,11 @@ func LoadEnv() (string, string, string) {
1818
log.Fatal("Nedostaje RPC_TESTNET_URL u .env fajlu")
1919
}
2020

21+
rpcMainnetURL := os.Getenv("RPC_MAINNET_URL")
22+
if rpcTestnetURL == "" {
23+
log.Fatal("Nedostaje RPC_TESTNET_URL u .env fajlu")
24+
}
25+
2126
recipient := os.Getenv("RECIPIENT_ADDRESS")
2227
if recipient == "" {
2328
log.Fatal("Nedostaje RECIPIENT_ADDRESS u .env fajlu")
@@ -28,5 +33,5 @@ func LoadEnv() (string, string, string) {
2833
log.Fatal("Nedostaje PRIVATE_KEY u .env fajlu")
2934
}
3035

31-
return rpcTestnetURL, recipient, privateKeyHex
36+
return rpcTestnetURL, rpcMainnetURL, recipient, privateKeyHex
3237
}

goCode/internal/rpc/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ type Transaction struct {
3030
Gas string `json:"gas"`
3131
GasPrice string `json:"gasPrice"`
3232
}
33+
34+
type TxSummary struct {
35+
BlockNumber uint64 `json:"block_number"`
36+
TxHash string `json:"tx_hash"`
37+
GasUsed uint64 `json:"gas_used"`
38+
PercentInBlock float64 `json:"percent_in_block"`
39+
}

rustCode/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ pub mod models;
22
pub mod rpc;
33
pub mod utils;
44

5-
use crate::rpc::fetch::fetch_latest_block;
5+
use crate::rpc::fetch::{fetch_latest_block, fetch_last_5_blocks_and_receipts};
66
use std::ffi::CString;
77
use std::os::raw::c_char;
8+
use crate::utils::hex_to_u64;
89

910
#[no_mangle]
1011
pub extern "C" fn fetch_transactions(rpc_url: *const c_char) -> *mut c_char {
@@ -34,3 +35,19 @@ pub extern "C" fn fetch_transactions(rpc_url: *const c_char) -> *mut c_char {
3435
// Vracanje C stringa koji Go moze koristiti
3536
c_str_result.into_raw()
3637
}
38+
39+
#[no_mangle]
40+
pub extern "C" fn fetch_last_5_blocks(rpc_url: *const c_char) -> *mut c_char {
41+
let c_rpc = unsafe { std::ffi::CStr::from_ptr(rpc_url) };
42+
let rpc_url_str = c_rpc.to_str().unwrap();
43+
44+
let runtime = tokio::runtime::Runtime::new().unwrap();
45+
let latest_block = runtime.block_on(fetch_latest_block(rpc_url_str, true));
46+
let latest_block_number = hex_to_u64(&latest_block.number);
47+
48+
let summaries = runtime.block_on(fetch_last_5_blocks_and_receipts(rpc_url_str.to_string(), latest_block_number));
49+
50+
let json_str = serde_json::to_string(&summaries).unwrap();
51+
let c_str_result = CString::new(json_str).unwrap();
52+
c_str_result.into_raw()
53+
}

rustCode/src/models/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub struct TransactionReceipt {
4444
pub cumulative_gas_used: String,
4545
}
4646

47+
#[derive(serde::Serialize)]
4748
pub struct TxSummary {
4849
pub block_number: String,
4950
pub tx_hash: String,

0 commit comments

Comments
 (0)