Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,14 @@ PORTAL_TOOLS_CSV := $(subst $(SPACE),$(COMMA),$(FLUFFY_TOOLS))
OS_PLATFORM = $(shell $(CC) -dumpmachine)
ifneq (, $(findstring darwin, $(OS_PLATFORM)))
SHAREDLIBEXT = dylib
STATICLIBEXT = a
else
ifneq (, $(findstring mingw, $(OS_PLATFORM))$(findstring cygwin, $(OS_PLATFORM))$(findstring msys, $(OS_PLATFORM)))
SHAREDLIBEXT = dll
STATICLIBEXT = lib
else
SHAREDLIBEXT = so
STATICLIBEXT = a
endif
endif

Expand Down Expand Up @@ -165,7 +168,7 @@ all: | $(TOOLS) nimbus nimbus_execution_client

# "-d:release" cannot be added to config.nims

NIM_PARAMS += -d:release
NIM_PARAMS += -d:debug
ifneq ($(if $(ENABLE_LINE_NUMBERS),$(ENABLE_LINE_NUMBERS),0),0)
NIM_PARAMS += -d:chronicles_line_numbers:1
endif
Expand Down Expand Up @@ -348,7 +351,8 @@ nimbus-verified-proxy-test: | build deps
libverifproxy: | build deps
+ echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim --version && \
$(ENV_SCRIPT) nim c --app:lib -d:"libp2p_pki_schemes=secp256k1" --noMain:on --threads:on --nimcache:nimcache/libverifproxy -o:$(VERIF_PROXY_OUT_PATH)/$@.$(SHAREDLIBEXT) $(NIM_PARAMS) nimbus_verified_proxy/libverifproxy/verifproxy.nim
echo $(NIM_PARAMS) && \
$(ENV_SCRIPT) nim c --app:staticlib -d:"libp2p_pki_schemes=secp256k1" --noMain:on --out:$(VERIF_PROXY_OUT_PATH)/$@.$(STATICLIBEXT) $(NIM_PARAMS) nimbus_verified_proxy/libverifproxy/verifproxy.nim
cp nimbus_verified_proxy/libverifproxy/verifproxy.h $(VERIF_PROXY_OUT_PATH)/
echo -e $(BUILD_END_MSG) "build/$@"

Expand Down
62 changes: 53 additions & 9 deletions nimbus_verified_proxy/lc/lc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import
chronicles,
chronos,
eth/common/keys, # used for keys.rng
beacon_chain/gossip_processing/light_client_processor,
beacon_chain/beacon_clock,
beacon_chain/[beacon_clock, conf],
./lc_manager # use the modified light client manager

type
Expand All @@ -20,8 +21,8 @@ type
) {.gcsafe, raises: [].}

LightClient* = ref object
cfg: RuntimeConfig
forkDigests: ref ForkDigests
cfg*: RuntimeConfig
forkDigests*: ref ForkDigests
getBeaconTime*: GetBeaconTimeFn
store*: ref ForkedLightClientStore
processor*: ref LightClientProcessor
Expand Down Expand Up @@ -144,16 +145,59 @@ proc new*(

lightClient

proc new*(
T: type LightClient, chain: Option[string], trustedBlockRoot: Option[Eth2Digest]
): T =
let metadata = loadEth2Network(chain)

# just for short hand convenience
template cfg(): auto =
metadata.cfg

# initialize beacon node genesis data, beacon clock and forkDigests
let
genesisState =
try:
template genesisData(): auto =
metadata.genesis.bakedBytes

newClone(
readSszForkedHashedBeaconState(
cfg, genesisData.toOpenArray(genesisData.low, genesisData.high)
)
)
except CatchableError as err:
raiseAssert "Invalid baked-in state: " & err.msg

# getStateField reads seeks info directly from a byte array
# get genesis time and instantiate the beacon clock
genesisTime = getStateField(genesisState[], genesis_time)
beaconClock = BeaconClock.init(cfg.timeParams, genesisTime).valueOr:
error "Invalid genesis time in state", genesisTime
quit QuitFailure

# get the function that itself get the current beacon time
getBeaconTime = beaconClock.getBeaconTimeFn()
genesis_validators_root = getStateField(genesisState[], genesis_validators_root)
forkDigests = newClone ForkDigests.init(cfg, genesis_validators_root)

rng = keys.newRng()

# light client is set to optimistic finalization mode
lightClient = LightClient.new(
rng, cfg, forkDigests, getBeaconTime, genesis_validators_root,
LightClientFinalizationMode.Optimistic,
)

lightClient.trustedBlockRoot = trustedBlockRoot
lightClient

proc setBackend*(lightClient: LightClient, backend: EthLCBackend) =
lightClient.manager.backend = backend

proc start*(lightClient: LightClient) =
proc start*(lightClient: LightClient) {.async: (raises: [CancelledError]).} =
info "Starting beacon light client", trusted_block_root = lightClient.trustedBlockRoot
lightClient.manager.start()

proc stop*(lightClient: LightClient) {.async: (raises: []).} =
info "Stopping beacon light client"
await lightClient.manager.stop()
await lightClient.manager.start()

proc resetToFinalizedHeader*(
lightClient: LightClient,
Expand Down
11 changes: 2 additions & 9 deletions nimbus_verified_proxy/lc/lc_manager.nim
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,6 @@ proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} =
# check for updates every slot
await sleepAsync(chronos.seconds(int64(self.timeParams.SECONDS_PER_SLOT)))

proc start*(self: var LightClientManager) =
proc start*(self: LightClientManager) {.async: (raises: [CancelledError]).} =
## Start light client manager's loop.
doAssert self.loopFuture == nil
self.loopFuture = self.loop()

proc stop*(self: var LightClientManager) {.async: (raises: []).} =
## Stop light client manager's loop.
if self.loopFuture != nil:
await noCancel self.loopFuture.cancelAndWait()
self.loopFuture = nil
await self.loop()
70 changes: 70 additions & 0 deletions nimbus_verified_proxy/libverifproxy/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* nimbus_verified_proxy
* Copyright (c) 2025 Status Research & Development GmbH
* Licensed and distributed under either of
* * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
* * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
* at your option. This file may not be copied, modified, or distributed except according to those terms.
*/

#include "./verifproxy.h"
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>

static bool waitOver = true;

void onBlockNumber(Context *ctx, int status, char *res) {
printf("Blocknumber: %s\n", res);
freeResponse(res);
}

void onStart(Context *ctx, int status, char *res) {
printf("Verified Proxy started successfully\n");
printf("status: %d\n", status);
printf("response: %s\n", res);
if (status < 0) stopVerifProxy(ctx);
freeResponse(res);
}

void onBalance(Context *ctx, int status, char *res) {
printf("Balance: %s\n", res);
freeResponse(res);
}

void waitIsOver(Context *ctx, int status, char *res) {
printf("waiting finished successfully\n");
printf("status: %d\n", status);

eth_blockNumber(ctx, onBlockNumber);
eth_getBalance(ctx, "0x954a86C613fd1fBaC9C7A43a071A68254C75E4AC", "latest", onBalance);
waitOver = true;

freeResponse(res);
}

int main() {
NimMain();
Context *ctx = createAsyncTaskContext();

char* jsonConfig =
"{"
"\"eth2Network\": \"mainnet\","
"\"trustedBlockRoot\": \"0xd9e4f5b2e7a8e50f9348a1890114ae522d3771ddfb44d8b7e7e2978c21869e91\","
"\"backendUrl\": \"https://eth.blockrazor.xyz\","
"\"beaconApiUrls\": \"http://testing.mainnet.beacon-api.nimbus.team,http://www.lightclientdata.org\","
"\"logLevel\": \"FATAL\","
"\"logStdout\": \"None\""
"}";

startVerifProxy(ctx, jsonConfig, onStart);

while(true) {
if (waitOver) {
waitOver = false;
nonBusySleep(ctx, 10, waitIsOver);
}
pollAsyncTaskEngine(ctx);
}
freeContext(ctx);
}
43 changes: 37 additions & 6 deletions nimbus_verified_proxy/libverifproxy/verifproxy.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* nimbus_verified_proxy
* Copyright (c) 2024 Status Research & Development GmbH
* Copyright (c) 2025 Status Research & Development GmbH
* Licensed and distributed under either of
* * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
* * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
Expand All @@ -10,12 +10,43 @@
#ifndef __verifproxy__
#define __verifproxy__

typedef struct VerifProxyContext VerifProxyContext;
typedef void (*onHeaderCallback)(const char* s, int t);
#ifdef __cplusplus
extern "C" {
#endif

void quit(void);
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif

VerifProxyContext* startVerifProxy(const char* configJson, onHeaderCallback onHeader);
void stopVerifProxy(VerifProxyContext*);
#ifndef __has_feature
#define __has_feature(x) 0
#endif

#if __has_attribute(warn_unused_result)
#define ETH_RESULT_USE_CHECK __attribute__((warn_unused_result))
#else
#define ETH_RESULT_USE_CHECK
#endif

void NimMain(void);

typedef struct Context Context;

ETH_RESULT_USE_CHECK Context *createAsyncTaskContext();

typedef void (*CallBackProc) (Context *ctx, int status, char *res);

void eth_getBalance(Context *ctx, char *address, char *blockTag, CallBackProc onBalance);
void eth_blockNumber(Context *ctx, CallBackProc cb);
void freeResponse(char *res);
void freeContext(Context *ctx);
void nonBusySleep(Context *ctx, int secs, CallBackProc cb);
void startVerifProxy(Context *ctx, char* configJson, CallBackProc onstart);
void stopVerifProxy(Context *ctx);
void pollAsyncTaskEngine(Context *ctx);

#ifdef __cplusplus
}
#endif

#endif /* __verifproxy__ */
Loading
Loading