Compare commits

...

5 Commits

5 changed files with 39 additions and 18 deletions

View File

@ -1,3 +1,5 @@
# [0.1.0-develop.30](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.29...v0.1.0-develop.30) (2023-07-13)
# [0.1.0-develop.29](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.28...v0.1.0-develop.29) (2023-07-13) # [0.1.0-develop.29](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.28...v0.1.0-develop.29) (2023-07-13)
# [0.1.0-develop.28](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.27...v0.1.0-develop.28) (2023-07-13) # [0.1.0-develop.28](https://git.lumeweb.com/LumeWeb/libethsync/compare/v0.1.0-develop.27...v0.1.0-develop.28) (2023-07-13)

4
npm-shrinkwrap.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@lumeweb/libethclient", "name": "@lumeweb/libethclient",
"version": "0.1.0-develop.29", "version": "0.1.0-develop.30",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@lumeweb/libethclient", "name": "@lumeweb/libethclient",
"version": "0.1.0-develop.29", "version": "0.1.0-develop.30",
"dependencies": { "dependencies": {
"@chainsafe/as-sha256": "^0.3.1", "@chainsafe/as-sha256": "^0.3.1",
"@chainsafe/bls": "7.1.1", "@chainsafe/bls": "7.1.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@lumeweb/libethsync", "name": "@lumeweb/libethsync",
"version": "0.1.0-develop.29", "version": "0.1.0-develop.30",
"type": "module", "type": "module",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -13,7 +13,11 @@ import {
getDefaultClientConfig, getDefaultClientConfig,
optimisticUpdateVerify, optimisticUpdateVerify,
} from "#util.js"; } from "#util.js";
import { LightClientUpdate, OptimisticUpdateCallback } from "#types.js"; import {
LightClientUpdate,
OptimisticUpdate,
OptimisticUpdateCallback,
} from "#types.js";
import { assertValidLightClientUpdate } from "@lodestar/light-client/validation"; import { assertValidLightClientUpdate } from "@lodestar/light-client/validation";
import * as capella from "@lodestar/types/capella"; import * as capella from "@lodestar/types/capella";
@ -35,6 +39,7 @@ export default abstract class BaseClient {
protected options: BaseClientOptions; protected options: BaseClientOptions;
private genesisTime = this.config.genesis.time; private genesisTime = this.config.genesis.time;
private syncMutex = new Mutex(); private syncMutex = new Mutex();
private optimisticMutex = new Mutex();
constructor(options: BaseClientOptions) { constructor(options: BaseClientOptions) {
this.options = options; this.options = options;
@ -101,10 +106,6 @@ export default abstract class BaseClient {
const curPeriod = startPeriod + i; const curPeriod = startPeriod + i;
const update = updates[i]; const update = updates[i];
const updatePeriod = computeSyncPeriodAtSlot(
update.attestedHeader.beacon.slot,
);
const validOrCommittee = await this.syncUpdateVerifyGetCommittee( const validOrCommittee = await this.syncUpdateVerifyGetCommittee(
startCommittee, startCommittee,
curPeriod, curPeriod,
@ -172,14 +173,39 @@ export default abstract class BaseClient {
protected async getLatestExecution(): Promise<ExecutionInfo | null> { protected async getLatestExecution(): Promise<ExecutionInfo | null> {
await this._sync(); await this._sync();
const getExecInfo = (u: OptimisticUpdate) => {
return {
blockHash: toHexString(u.attestedHeader.execution.blockHash),
blockNumber: u.attestedHeader.execution.blockNumber,
};
};
if (this._latestOptimisticUpdate) {
const update = capella.ssz.LightClientOptimisticUpdate.deserialize(
this._latestOptimisticUpdate,
);
const diffInSeconds = Date.now() / 1000 - this.genesisTime;
const currentSlot = Math.floor(
diffInSeconds / this.config.chainConfig.SECONDS_PER_SLOT,
);
if (currentSlot <= update.attestedHeader.beacon.slot) {
this.optimisticMutex.release();
return getExecInfo(update);
}
}
await this.optimisticMutex.acquire();
const update = await this.options.optimisticUpdateCallback(); const update = await this.options.optimisticUpdateCallback();
const verify = await optimisticUpdateVerify( const verify = await optimisticUpdateVerify(
this.latestCommittee as Uint8Array[], this.latestCommittee as Uint8Array[],
update, update,
); );
// TODO: check the update against the latest sync committee // TODO: check the update against the latest sync committee
if (!verify.correct) { if (!verify.correct) {
this.optimisticMutex.release();
console.error(`Invalid Optimistic Update: ${verify.reason}`); console.error(`Invalid Optimistic Update: ${verify.reason}`);
return null; return null;
} }
@ -191,10 +217,9 @@ export default abstract class BaseClient {
`Optimistic update verified for slot ${update.attestedHeader.beacon.slot}`, `Optimistic update verified for slot ${update.attestedHeader.beacon.slot}`,
); );
return { this.optimisticMutex.release();
blockHash: toHexString(update.attestedHeader.execution.blockHash),
blockNumber: update.attestedHeader.execution.blockNumber, return getExecInfo(update);
};
} }
protected async syncUpdateVerifyGetCommittee( protected async syncUpdateVerifyGetCommittee(

View File

@ -25,10 +25,4 @@ export default class Client extends BaseClient {
this.beaconUrl = config.beaconUrl; this.beaconUrl = config.beaconUrl;
this.http.defaults.baseURL = this.beaconUrl; this.http.defaults.baseURL = this.beaconUrl;
} }
async sync(): Promise<void> {
await super.sync();
this.subscribe();
}
} }