From 4dab5ca929f360da468dd02a5250a06fb9a82ded Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Wed, 9 Oct 2024 15:12:38 -0400 Subject: [PATCH 01/12] feat(light-client): Update contract to trusted setup --- .../solidity/contracts/bridge/src/utils/Verifier.sol | 8 ++++---- .../solidity/extract_proof_and_public_from_redis.sh | 2 +- .../solidity/test/BeaconLightClientReadyProofs.test.ts | 8 ++++---- .../process-compose-scripts/download-zk-and-dat-files.sh | 2 +- tsconfig.json | 2 +- vendor/eth2-light-client-updates | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol b/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol index 0f0c5ae4e..8e61417a4 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol @@ -37,10 +37,10 @@ contract Groth16Verifier { uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - uint256 constant deltax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; - uint256 constant deltax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; - uint256 constant deltay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; - uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; + uint256 constant deltax1 = 2343236923834963358037492110423434801285275176030641534786585479610777991492; + uint256 constant deltax2 = 7354734418275536777818704753730665460248350105717340249623478132690757632061; + uint256 constant deltay1 = 14156031723817663434631995261455976608108837842676842217057543351737739467454; + uint256 constant deltay2 = 20646074624478348418892142743169842075310032726102859617297640617605155938039; uint256 constant IC0x = 15885245864077738868080438953982725331851392259561989715709451737775650751499; diff --git a/beacon-light-client/solidity/extract_proof_and_public_from_redis.sh b/beacon-light-client/solidity/extract_proof_and_public_from_redis.sh index 76321adf8..ea78718ce 100755 --- a/beacon-light-client/solidity/extract_proof_and_public_from_redis.sh +++ b/beacon-light-client/solidity/extract_proof_and_public_from_redis.sh @@ -45,7 +45,7 @@ for key in ${keys}; do # Use jq to extract pi_a, pi_b, pi_c, and public extracted_proof=$(echo "${json_data}" | jq '.proof | {pi_a, pi_b, pi_c}') - extracted_public=$(echo "${json_data}" | jq '.public') + extracted_public=$(echo "${json_data}" | jq '.proof.public') # Extract update data from proofInput nextHeaderHash_bin=$(echo "${json_data}" | jq -r '.proofInput.nextHeaderHash // empty | map(.) | join("")') diff --git a/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts b/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts index 8e028b174..4de1e47c0 100644 --- a/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts +++ b/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts @@ -6,7 +6,7 @@ import { getFilesInDir, Proof } from './utils'; import { convertProofToSolidityCalldata } from '@dendreth/utils/ts-utils/zk-utils'; import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; -import INITIAL_UPDATE from '../../../vendor/eth2-light-client-updates/mainnet/deneb-update-284/update_9265121_9273312.json'; +import INITIAL_UPDATE from '../../../vendor/eth2-light-client-updates/mainnet/trusted-setup/update_6069888_6078433.json'; const logger = getGenericLogger(); @@ -26,7 +26,7 @@ describe('BeaconLightClientReadyProofs', async function () { 'vendor', 'eth2-light-client-updates', 'mainnet', - 'deneb-update-284', + 'trusted-setup', ); proofs = getFilesInDir(dir, 'proof*.json').map(p => @@ -43,9 +43,9 @@ describe('BeaconLightClientReadyProofs', async function () { }); beforeEach(async function () { - const FORK_VERSION = '0x04000000'; + const FORK_VERSION = '0x90000073'; const genesis_validators_root = - '0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95'; + '0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078'; const DOMAIN_SYNC_COMMITTEE = '0x07000000'; let result = sha256( diff --git a/relay/process-compose-scripts/download-zk-and-dat-files.sh b/relay/process-compose-scripts/download-zk-and-dat-files.sh index 5d2e3072b..9863c32a4 100755 --- a/relay/process-compose-scripts/download-zk-and-dat-files.sh +++ b/relay/process-compose-scripts/download-zk-and-dat-files.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -ZKEY_B3SUM_SUM='7bd1baf6e4aa1bb97933df06f68b26f8aa034e6743ff52c4dd7f6097d6e7d104' +ZKEY_B3SUM_SUM='e5cb635fd494414d599fb22fc132f8ff9ecbc811d7cfc2557b1d8af55165fdad' DAT_B3SUM_SUM='c94eb86af7c0451a4277a7bdfc90232a9db75c192d6852ad18baa9a46e1e52e5' source "${GIT_ROOT}/.env" diff --git a/tsconfig.json b/tsconfig.json index 6c47dfd43..18798f787 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -105,6 +105,6 @@ }], "files": ["vendor/eth2-light-client-updates/mainnet/bootstrap.json", "vendor/eth2-light-client-updates/mainnet/updates/00290.json", - "vendor/eth2-light-client-updates/mainnet/deneb-update-284/update_9265121_9273312.json"], + "vendor/eth2-light-client-updates/mainnet/trusted-setup/update_6069888_6078433.json"], "include": ["**/*.ts", "**/*.json"] } diff --git a/vendor/eth2-light-client-updates b/vendor/eth2-light-client-updates index f7ff6f3a5..03c16e7f0 160000 --- a/vendor/eth2-light-client-updates +++ b/vendor/eth2-light-client-updates @@ -1 +1 @@ -Subproject commit f7ff6f3a5c4b74ab753b91472a075f12eda83d6f +Subproject commit 03c16e7f0b3533833a5476ade9e70855ecb493ee From afe737399ebe163bc846fb585ba2af1993590660 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Sun, 3 Nov 2024 16:13:37 -0500 Subject: [PATCH 02/12] feat(light-client): Restrict lightClientUpdate function --- .../bridge/src/interfaces/ILightClient.sol | 4 +- .../src/truth/eth/BeaconLightClient.sol | 37 +++++++++++------ .../src/utils/LightClientUpdateVerifier.sol | 2 +- .../solidity/tasks/change-adapter-address.ts | 41 +++++++++++++++++++ beacon-light-client/solidity/tasks/index.ts | 1 + process-compose.yaml | 2 +- .../download-zk-and-dat-files.sh | 5 --- 7 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 beacon-light-client/solidity/tasks/change-adapter-address.ts diff --git a/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol b/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol index 2e1721630..dde35f024 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.9; +pragma solidity 0.8.20; interface ILightClient { struct LightClientUpdate { @@ -32,5 +32,5 @@ interface ILightClient { function lightClientUpdate( LightClientUpdate calldata update - ) external payable; + ) external; } diff --git a/beacon-light-client/solidity/contracts/bridge/src/truth/eth/BeaconLightClient.sol b/beacon-light-client/solidity/contracts/bridge/src/truth/eth/BeaconLightClient.sol index ad13442f8..e4768c1f7 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/truth/eth/BeaconLightClient.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/truth/eth/BeaconLightClient.sol @@ -1,12 +1,16 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.9; +pragma solidity 0.8.20; import '../../utils/LightClientUpdateVerifier.sol'; import '../../interfaces/ILightClient.sol'; +import '@openzeppelin/contracts/access/Ownable.sol'; uint256 constant BUFER_SIZE = 32; -contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { +contract BeaconLightClient is Ownable, LightClientUpdateVerifier, ILightClient { + error ProofVerificationFailed(); + error InvalidAccessControll(); + bytes32[BUFER_SIZE] public optimisticHeaders; uint256[BUFER_SIZE] public optimisticSlots; @@ -19,13 +23,15 @@ contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { bytes32 domain; + address adapterAddress; + constructor( bytes32 _optimisticHeaderRoot, uint256 _optimisticHeaderSlot, bytes32 _finalizedHeaderRoot, bytes32 _executionStateRoot, bytes32 _domain - ) { + ) Ownable(msg.sender) { currentIndex = 0; optimisticHeaders[currentIndex] = _optimisticHeaderRoot; @@ -51,13 +57,17 @@ contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { return executionStateRoots[currentIndex]; } - // TODO: fix name to lightClientUpdate - function lightClientUpdate(LightClientUpdate calldata update) - external - payable - { - require( - verifyUpdate( + function changeAdapterAddress(address _adapterAddress) external onlyOwner { + adapterAddress = _adapterAddress; + } + + function lightClientUpdate(LightClientUpdate calldata update) external { + if (msg.sender != adapterAddress && msg.sender != owner()) { + revert InvalidAccessControll(); + } + + if ( + !verifyUpdate( update.a, update.b, update.c, @@ -67,9 +77,10 @@ contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { update.finalizedHeaderRoot, update.finalizedExecutionStateRoot, domain - ), - '!proof' - ); + ) + ) { + revert ProofVerificationFailed(); + } currentIndex = (currentIndex + 1) % BUFER_SIZE; diff --git a/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol b/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol index 76629582f..7acb00b2e 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.9; +pragma solidity 0.8.20; import './Verifier.sol'; diff --git a/beacon-light-client/solidity/tasks/change-adapter-address.ts b/beacon-light-client/solidity/tasks/change-adapter-address.ts new file mode 100644 index 000000000..3e51036c7 --- /dev/null +++ b/beacon-light-client/solidity/tasks/change-adapter-address.ts @@ -0,0 +1,41 @@ +import { task } from 'hardhat/config'; +import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; +import Web3 from 'web3'; +import { publishTransaction } from '@dendreth/relay/implementations/publish_evm_transaction'; + +const logger = getGenericLogger(); + +task('change-adapter-address', 'Verify') + .addParam('lightClient', 'The address of the BeaconLightClient contract') + .addParam('adapter', 'The address of the adapter contract') + .addParam( + 'transactionSpeed', + 'The speed you want the transactions to be included in a block', + 'avg', + undefined, + true, + ) + .setAction(async (args, { network, ethers }) => { + const [publisher] = await ethers.getSigners(); + + logger.info(`Changing adapter with address ${publisher.address}`); + + const lightClientContract = await ethers.getContractAt( + 'BeaconLightClient', + args.lightClient, + publisher, + ); + + const web3 = new Web3((network.config as any).url); + + await publishTransaction( + lightClientContract, + 'changeAdapterAddress', + [args.adapter], + web3, + args.transactionSpeed, + true, + ); + + logger.info(`Adapter changed to ${args.adapter}`); + }); diff --git a/beacon-light-client/solidity/tasks/index.ts b/beacon-light-client/solidity/tasks/index.ts index 292065cd8..3d807dea5 100644 --- a/beacon-light-client/solidity/tasks/index.ts +++ b/beacon-light-client/solidity/tasks/index.ts @@ -5,3 +5,4 @@ import './start-publishing'; import './remove-repeat-job'; import './deploy-balance-verifier'; import './balance-verifier-publisher'; +import './change-adapter-address'; diff --git a/process-compose.yaml b/process-compose.yaml index c3d7f48de..bbb91825e 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -138,7 +138,7 @@ processes: gnosis: description: Start generating proofs for the contract on ${LC_GNOSIS} and update it with them log_location: ./logs/gnosis.log - command: yarn hardhat start-publishing --light-client ${LC_GNOSIS} --network gnosis --follow-network ${FOLLOW_NETWORK_GNOSIS} --slots-jump ${SLOTS_JUMP} --prometheus-port 3014 + command: yarn hardhat start-publishing --light-client ${LC_GNOSIS} --network gnosis --follow-network ${FOLLOW_NETWORK_GNOSIS} --slots-jump ${SLOTS_JUMP} --hashi ${GNOSIS_HASHI} --prometheus-port 3014 working_dir: ./beacon-light-client/solidity depends_on: proverserver: diff --git a/relay/process-compose-scripts/download-zk-and-dat-files.sh b/relay/process-compose-scripts/download-zk-and-dat-files.sh index 9863c32a4..9f351217f 100755 --- a/relay/process-compose-scripts/download-zk-and-dat-files.sh +++ b/relay/process-compose-scripts/download-zk-and-dat-files.sh @@ -99,8 +99,3 @@ if [ -z "${SLOTS_JUMP}" ]; then echo "Error: SLOTS_JUMP environment variable is not set. Exiting..." exit 1 fi - -if [[ "${PRATTER}" != "TRUE" && "${MAINNET}" != "TRUE" ]]; then - echo "Neither PRATTER nor MAINNET is set or true." - exit 1 -fi From 9cb78708b86426567bcb2f48c8b1db37efb35ad8 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Fri, 8 Nov 2024 15:53:09 -0500 Subject: [PATCH 03/12] fix(relay): Bug when finalized slot is in previous period --- relay/utils/orchestrator.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/relay/utils/orchestrator.ts b/relay/utils/orchestrator.ts index a57ffbe67..a59b7b32c 100644 --- a/relay/utils/orchestrator.ts +++ b/relay/utils/orchestrator.ts @@ -29,8 +29,12 @@ export async function addUpdate( } } + const finalizedSlot = ( + await beaconApi.getFinalizedBlockHeader(optimisticSlot) + ).slot; + const nextSlot = await getNextSlot( - optimisticSlot, + finalizedSlot, slotsJump, headSlot, beaconApi, From 05fd36bc96d3446b0c3c7725092ff17ab4ad10b2 Mon Sep 17 00:00:00 2001 From: Kristin Kirkov Date: Tue, 10 Dec 2024 18:03:00 +0200 Subject: [PATCH 04/12] feat(beaconApi): Add getDomainSyncCommittee and getForkVersion to beaconApi class --- relay/abstraction/beacon-api-interface.ts | 4 ++++ relay/implementations/beacon-api.ts | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/relay/abstraction/beacon-api-interface.ts b/relay/abstraction/beacon-api-interface.ts index d531c8f0c..7664d7ce8 100644 --- a/relay/abstraction/beacon-api-interface.ts +++ b/relay/abstraction/beacon-api-interface.ts @@ -62,4 +62,8 @@ export interface IBeaconApi { getFinalizedBlockHeader(slot: number): Promise; getExecutionStateRoot(slot: number): Promise; + + getDomainSyncCommittee(): Promise; + + getForkVersion(): Promise; } diff --git a/relay/implementations/beacon-api.ts b/relay/implementations/beacon-api.ts index 1ee3e4bb2..79ef7cf23 100644 --- a/relay/implementations/beacon-api.ts +++ b/relay/implementations/beacon-api.ts @@ -150,6 +150,7 @@ export class BeaconApi implements IBeaconApi { (await this.fetchWithFallback('/eth/v1/beacon/headers/head')).json(), 'getCurrentHeadSlot', ); + logger.info('CurrentHeadSlot: ', currentHead.data.header.message.slot); return Number(currentHead.data.header.message.slot); } @@ -173,7 +174,10 @@ export class BeaconApi implements IBeaconApi { await this.fetchWithFallback(`/eth/v1/beacon/headers/${blockHash}`) ).json(); - logger.info('Got CurrentHeadSlot..'); + logger.info( + 'Got CurrentHeadSlot..', + await Number(headResult.data.header.message.slot), + ); return Number(headResult.data.header.message.slot); } @@ -611,6 +615,23 @@ export class BeaconApi implements IBeaconApi { return { beaconState, stateTree }; } + async getDomainSyncCommittee(): Promise { + const config = await ( + await this.fetchWithFallback('/eth/v1/config/spec') + ).json(); + + const domainSyncCommittee = config.data.DOMAIN_SYNC_COMMITTEE; + return domainSyncCommittee; + } + + async getForkVersion(): Promise { + const config = await ( + await this.fetchWithFallback('/eth/v1/config/spec') + ).json(); + + const forkVersion = config.data.DENEB_FORK_VERSION; + return forkVersion; + } private nextApi(): void { this.currentApiIndex = (this.currentApiIndex + 1) % this.beaconRestApis.length; From 244544b2bd4bb84ab2978608923efe2e9df953ad Mon Sep 17 00:00:00 2001 From: Kristin Kirkov Date: Tue, 10 Dec 2024 18:04:03 +0200 Subject: [PATCH 05/12] ref(relay-utils): Refactor getNetworkConfig func to use beaconApi class --- relay/utils/get_current_network_config.ts | 75 ++++++++--------------- yarn-project.nix | 72 +++++++++++----------- 2 files changed, 60 insertions(+), 87 deletions(-) diff --git a/relay/utils/get_current_network_config.ts b/relay/utils/get_current_network_config.ts index 6b7cef03a..0e5b472b8 100644 --- a/relay/utils/get_current_network_config.ts +++ b/relay/utils/get_current_network_config.ts @@ -1,3 +1,6 @@ +import { BeaconApi, getBeaconApi } from '@/implementations/beacon-api'; +import { bytesToHex } from '@dendreth/utils/ts-utils/bls'; + interface Config { NETWORK_NAME: string; BEACON_REST_API: string[]; @@ -40,60 +43,30 @@ export async function getNetworkConfig( ): Promise { let config: Config = { ...defaultConfig, NETWORK_NAME: network }; config.NETWORK_NAME = network; - switch (network) { - case 'pratter': { - config.BEACON_REST_API[0] = - process.env.BEACON_REST_API_PRATER || 'default_prater_rest_api_url'; - break; - } - case 'mainnet': { - config.BEACON_REST_API[0] = - process.env.BEACON_REST_API_MAINNET || 'default_mainnet_rest_api_url'; - break; - } - case 'sepolia': { - config.BEACON_REST_API[0] = - process.env.BEACON_REST_API_SEPOLIA || 'default_sepolia_rest_api_url'; - break; - } - case 'chiado': { - config.BEACON_REST_API[0] = - process.env.BEACON_REST_API_CHIADO || 'default_chiado_rest_api_url'; - break; - } - case 'gnosis': { - config.BEACON_REST_API[0] = - process.env.BEACON_REST_API_GNOSIS || 'default_gnosis_rest_api_url'; - break; - } - default: { - throw new Error('Network not supported'); - break; - } - } - const response = await fetch(config.BEACON_REST_API + '/eth/v1/config/spec'); - if (!response.ok) { - throw new Error('Network response was not ok ' + response.statusText); - } - const responseGenesis = await fetch( - config.BEACON_REST_API + '/eth/v1/beacon/genesis', - ); - if (!responseGenesis.ok) { - throw new Error( - 'Network response was not ok ' + responseGenesis.statusText, - ); + const envVarName = `BEACON_REST_API_${network.toUpperCase()}`; + const envVarValue = process.env[envVarName]; + + if (!envVarValue) { + throw new Error(`${envVarName} is not defined`); } - const config_ = await response.json(); - const config_genesis = await responseGenesis.json(); - config.SLOTS_PER_EPOCH = config_.data.SLOTS_PER_EPOCH; - config.EPOCHS_PER_SYNC_COMMITTEE_PERIOD = - config_.data.EPOCHS_PER_SYNC_COMMITTEE_PERIOD; - config.GENESIS_FORK_VERSION = config_.data.GENESIS_FORK_VERSION; - config.FORK_VERSION = config_.data.DENEB_FORK_VERSION; - config.DOMAIN_SYNC_COMMITTEE = config_.data.DOMAIN_SYNC_COMMITTEE; - config.GENESIS_VALIDATORS_ROOT = config_genesis.data.genesis_validators_root; + config.BEACON_REST_API = envVarValue.split(','); + + const beaconApi = await getBeaconApi(config.BEACON_REST_API); + + const config_genesis = await beaconApi.getGenesisData(); + + config.SLOTS_PER_EPOCH = Number(await beaconApi.getSlotsPerEpoch()); + config.EPOCHS_PER_SYNC_COMMITTEE_PERIOD = Number( + await beaconApi.getSlotsPerSyncCommitteePeriod(), + ); + config.GENESIS_FORK_VERSION = bytesToHex(config_genesis.genesisForkVersion); + config.FORK_VERSION = await beaconApi.getForkVersion(); + config.DOMAIN_SYNC_COMMITTEE = await beaconApi.getDomainSyncCommittee(); + config.GENESIS_VALIDATORS_ROOT = bytesToHex( + config_genesis.genesisValidatorsRoot, + ); return config; } diff --git a/yarn-project.nix b/yarn-project.nix index 655681739..43162e690 100644 --- a/yarn-project.nix +++ b/yarn-project.nix @@ -130,61 +130,61 @@ let "bufferutil@npm:4.0.8" \ ${isolated."bufferutil@npm:4.0.8"} \ ".yarn/unplugged/bufferutil-npm-4.0.8-8005ed6210/node_modules/bufferutil" - echo 'injecting build for utf-8-validate' + echo 'injecting build for secp256k1' yarn nixify inject-build \ - "utf-8-validate@npm:5.0.10" \ - ${isolated."utf-8-validate@npm:5.0.10"} \ - ".yarn/unplugged/utf-8-validate-npm-5.0.10-93e9b6f750/node_modules/utf-8-validate" + "secp256k1@npm:4.0.3" \ + ${isolated."secp256k1@npm:4.0.3"} \ + ".yarn/unplugged/secp256k1-npm-4.0.3-b4e9ce065b/node_modules/secp256k1" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.4" \ ${isolated."keccak@npm:3.0.4"} \ ".yarn/unplugged/keccak-npm-3.0.4-a84763aab8/node_modules/keccak" - echo 'injecting build for secp256k1' + echo 'injecting build for utf-8-validate' yarn nixify inject-build \ - "secp256k1@npm:4.0.3" \ - ${isolated."secp256k1@npm:4.0.3"} \ - ".yarn/unplugged/secp256k1-npm-4.0.3-b4e9ce065b/node_modules/secp256k1" - echo 'injecting build for bcrypto' + "utf-8-validate@npm:5.0.7" \ + ${isolated."utf-8-validate@npm:5.0.7"} \ + ".yarn/unplugged/utf-8-validate-npm-5.0.7-88d731f8ad/node_modules/utf-8-validate" + echo 'injecting build for utf-8-validate' yarn nixify inject-build \ - "bcrypto@npm:5.5.2" \ - ${isolated."bcrypto@npm:5.5.2"} \ - ".yarn/unplugged/bcrypto-npm-5.5.2-f3838b92ce/node_modules/bcrypto" + "utf-8-validate@npm:5.0.10" \ + ${isolated."utf-8-validate@npm:5.0.10"} \ + ".yarn/unplugged/utf-8-validate-npm-5.0.10-93e9b6f750/node_modules/utf-8-validate" echo 'injecting build for blake-hash' yarn nixify inject-build \ "blake-hash@npm:2.0.0" \ ${isolated."blake-hash@npm:2.0.0"} \ ".yarn/unplugged/blake-hash-npm-2.0.0-c63b9a2c2d/node_modules/blake-hash" - echo 'injecting build for bcrypt' + echo 'injecting build for bufferutil' yarn nixify inject-build \ - "bcrypt@npm:5.0.1" \ - ${isolated."bcrypt@npm:5.0.1"} \ - ".yarn/unplugged/bcrypt-npm-5.0.1-6815be1cfe/node_modules/bcrypt" + "bufferutil@npm:4.0.5" \ + ${isolated."bufferutil@npm:4.0.5"} \ + ".yarn/unplugged/bufferutil-npm-4.0.5-88cc521694/node_modules/bufferutil" + echo 'injecting build for leveldown' + yarn nixify inject-build \ + "leveldown@npm:6.1.0" \ + ${isolated."leveldown@npm:6.1.0"} \ + ".yarn/unplugged/leveldown-npm-6.1.0-c2d7a4250d/node_modules/leveldown" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.1" \ ${isolated."keccak@npm:3.0.1"} \ ".yarn/unplugged/keccak-npm-3.0.1-9f0a714d5c/node_modules/keccak" - echo 'injecting build for bufferutil' - yarn nixify inject-build \ - "bufferutil@npm:4.0.5" \ - ${isolated."bufferutil@npm:4.0.5"} \ - ".yarn/unplugged/bufferutil-npm-4.0.5-88cc521694/node_modules/bufferutil" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.2" \ ${isolated."keccak@npm:3.0.2"} \ ".yarn/unplugged/keccak-npm-3.0.2-6e9dec8765/node_modules/keccak" - echo 'injecting build for leveldown' + echo 'injecting build for bcrypt' yarn nixify inject-build \ - "leveldown@npm:6.1.0" \ - ${isolated."leveldown@npm:6.1.0"} \ - ".yarn/unplugged/leveldown-npm-6.1.0-c2d7a4250d/node_modules/leveldown" - echo 'injecting build for utf-8-validate' + "bcrypt@npm:5.0.1" \ + ${isolated."bcrypt@npm:5.0.1"} \ + ".yarn/unplugged/bcrypt-npm-5.0.1-6815be1cfe/node_modules/bcrypt" + echo 'injecting build for bcrypto' yarn nixify inject-build \ - "utf-8-validate@npm:5.0.7" \ - ${isolated."utf-8-validate@npm:5.0.7"} \ - ".yarn/unplugged/utf-8-validate-npm-5.0.7-88d731f8ad/node_modules/utf-8-validate" + "bcrypto@npm:5.5.2" \ + ${isolated."bcrypto@npm:5.5.2"} \ + ".yarn/unplugged/bcrypto-npm-5.5.2-f3838b92ce/node_modules/bcrypto" echo 'injecting build for redis-commander' yarn nixify inject-build \ "redis-commander@npm:0.8.0" \ @@ -249,16 +249,16 @@ let isolated."msgpackr-extract@npm:3.0.2" = optionalOverride (args.overrideMsgpackrExtractAttrs or null) (mkIsolatedBuild { pname = "msgpackr-extract"; version = "3.0.2"; reference = "npm:3.0.2"; }); isolated."bufferutil@npm:4.0.8" = optionalOverride (args.overrideBufferutilAttrs or null) (mkIsolatedBuild { pname = "bufferutil"; version = "4.0.8"; reference = "npm:4.0.8"; }); -isolated."utf-8-validate@npm:5.0.10" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.10"; reference = "npm:5.0.10"; }); -isolated."keccak@npm:3.0.4" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.4"; reference = "npm:3.0.4"; }); isolated."secp256k1@npm:4.0.3" = optionalOverride (args.overrideSecp256k1Attrs or null) (mkIsolatedBuild { pname = "secp256k1"; version = "4.0.3"; reference = "npm:4.0.3"; }); -isolated."bcrypto@npm:5.5.2" = optionalOverride (args.overrideBcryptoAttrs or null) (mkIsolatedBuild { pname = "bcrypto"; version = "5.5.2"; reference = "npm:5.5.2"; }); +isolated."keccak@npm:3.0.4" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.4"; reference = "npm:3.0.4"; }); +isolated."utf-8-validate@npm:5.0.7" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.7"; reference = "npm:5.0.7"; }); +isolated."utf-8-validate@npm:5.0.10" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.10"; reference = "npm:5.0.10"; }); isolated."blake-hash@npm:2.0.0" = optionalOverride (args.overrideBlakeHashAttrs or null) (mkIsolatedBuild { pname = "blake-hash"; version = "2.0.0"; reference = "npm:2.0.0"; }); -isolated."bcrypt@npm:5.0.1" = optionalOverride (args.overrideBcryptAttrs or null) (mkIsolatedBuild { pname = "bcrypt"; version = "5.0.1"; reference = "npm:5.0.1"; }); -isolated."keccak@npm:3.0.1" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.1"; reference = "npm:3.0.1"; }); isolated."bufferutil@npm:4.0.5" = optionalOverride (args.overrideBufferutilAttrs or null) (mkIsolatedBuild { pname = "bufferutil"; version = "4.0.5"; reference = "npm:4.0.5"; }); -isolated."keccak@npm:3.0.2" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.2"; reference = "npm:3.0.2"; }); isolated."leveldown@npm:6.1.0" = optionalOverride (args.overrideLeveldownAttrs or null) (mkIsolatedBuild { pname = "leveldown"; version = "6.1.0"; reference = "npm:6.1.0"; }); -isolated."utf-8-validate@npm:5.0.7" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.7"; reference = "npm:5.0.7"; }); +isolated."keccak@npm:3.0.1" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.1"; reference = "npm:3.0.1"; }); +isolated."keccak@npm:3.0.2" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.2"; reference = "npm:3.0.2"; }); +isolated."bcrypt@npm:5.0.1" = optionalOverride (args.overrideBcryptAttrs or null) (mkIsolatedBuild { pname = "bcrypt"; version = "5.0.1"; reference = "npm:5.0.1"; }); +isolated."bcrypto@npm:5.5.2" = optionalOverride (args.overrideBcryptoAttrs or null) (mkIsolatedBuild { pname = "bcrypto"; version = "5.5.2"; reference = "npm:5.5.2"; }); isolated."redis-commander@npm:0.8.0" = optionalOverride (args.overrideRedisCommanderAttrs or null) (mkIsolatedBuild { pname = "redis-commander"; version = "0.8.0"; reference = "npm:0.8.0"; }); in overriddenProject From a6604840c867c14f08115b0234ccf2c1ecf3465f Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Wed, 11 Dec 2024 06:55:00 -0500 Subject: [PATCH 06/12] feat: Increase discord monitor look back --- relay/utils/discord_monitor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/utils/discord_monitor.ts b/relay/utils/discord_monitor.ts index 9fa49e93c..731139151 100644 --- a/relay/utils/discord_monitor.ts +++ b/relay/utils/discord_monitor.ts @@ -12,7 +12,7 @@ async function getLastEventTime( const events = await contract.queryFilter( filter, - latestBlock - 10000, + latestBlock - 100000, latestBlock, ); if (events.length === 0) { From 21d67352ebd16aee052251d1cf40f8dd43233758 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Tue, 7 Jan 2025 11:32:39 +0200 Subject: [PATCH 07/12] feat: Make seconds per slot configurable --- relay/constants/constants.ts | 2 + relay/implementations/beacon-api.ts | 9 +++ relay/on_chain_publisher.ts | 15 ++++- relay/utils/get_current_network_config.ts | 3 + yarn-project.nix | 72 +++++++++++------------ 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/relay/constants/constants.ts b/relay/constants/constants.ts index f04bf72ea..d3a7e5a41 100644 --- a/relay/constants/constants.ts +++ b/relay/constants/constants.ts @@ -1,5 +1,6 @@ export type Config = { SLOTS_PER_EPOCH: number; + SECONDS_PER_SLOT: number; EPOCHS_PER_SYNC_COMMITTEE_PERIOD: number; GENESIS_FORK_VERSION: string; FORK_VERSION: string; @@ -10,6 +11,7 @@ export type Config = { export const PRATER: Config = { SLOTS_PER_EPOCH: 32, + SECONDS_PER_SLOT: 12, EPOCHS_PER_SYNC_COMMITTEE_PERIOD: 256, GENESIS_FORK_VERSION: '0x00001020', FORK_VERSION: '0x03001020', diff --git a/relay/implementations/beacon-api.ts b/relay/implementations/beacon-api.ts index 79ef7cf23..915add4a0 100644 --- a/relay/implementations/beacon-api.ts +++ b/relay/implementations/beacon-api.ts @@ -44,6 +44,15 @@ export class BeaconApi implements IBeaconApi { return BigInt(slotsPerEpoch); } + async getSecondsPerSlot(): Promise { + const config = await ( + await this.fetchWithFallback('/eth/v1/config/spec') + ).json(); + + const secondsPerSlot = config.data.SECONDS_PER_SLOT; + return secondsPerSlot; + } + async getSlotsPerSyncCommitteePeriod(): Promise { const config = await ( await this.fetchWithFallback('/eth/v1/config/spec') diff --git a/relay/on_chain_publisher.ts b/relay/on_chain_publisher.ts index 1bc368258..9978dc4f2 100644 --- a/relay/on_chain_publisher.ts +++ b/relay/on_chain_publisher.ts @@ -53,6 +53,7 @@ export async function publishProofs( beaconApi, smartContract, hashiAdapterContract, + networkConfig, rpcEndpoint, transactionSpeed, networkName, @@ -65,6 +66,7 @@ export async function publishProofs( beaconApi, smartContract, hashiAdapterContract, + networkConfig, rpcEndpoint, transactionSpeed, ); @@ -83,6 +85,7 @@ export async function drainUpdatesInRedis( beaconApi: IBeaconApi, smartContract: ISmartContract, hashiAdapterContract: Contract | undefined, + networkConfig: Config, rpcEndpoint?: string, transactionSpeed: TransactionSpeed = 'avg', networkName?: string, @@ -112,6 +115,7 @@ export async function drainUpdatesInRedis( beaconApi, lastSlotOnChain, hashiAdapterContract, + networkConfig, rpcEndpoint, transactionSpeed, networkName, @@ -142,6 +146,7 @@ export async function postUpdateOnChain( beaconApi: IBeaconApi, lastSlotOnChain: number, hashiAdapterContract: Contract | undefined, + networkConfig: Config, rpcEndpoint?: string, transactionSpeed: TransactionSpeed = 'avg', networkName?: string, @@ -214,10 +219,12 @@ export async function postUpdateOnChain( logger.info(`Current slot on the network is ${currentHeadSlot}`); - let prevSlotBehind = ((currentHeadSlot - lastSlotOnChain) * 12) / 60; + let prevSlotBehind = + ((currentHeadSlot - lastSlotOnChain) * networkConfig.SECONDS_PER_SLOT) / 60; logger.info(`Prev slot is ${prevSlotBehind} minutes behind`); - let transactionBehind = ((currentHeadSlot - transactionSlot) * 12) / 60; + let transactionBehind = + ((currentHeadSlot - transactionSlot) * networkConfig.SECONDS_PER_SLOT) / 60; logger.info(`Transaction is ${transactionBehind} minutes behind`); if (networkName) { @@ -289,7 +296,9 @@ async function askForUpdates( ) {} let after = Date.now(); - await sleep(12000 * slotsJump - (after - before)); + await sleep( + networkConfig.SECONDS_PER_SLOT * 1000 * slotsJump - (after - before), + ); } catch (e) { logger.error(`Error while fetching update ${e}`); } diff --git a/relay/utils/get_current_network_config.ts b/relay/utils/get_current_network_config.ts index 0e5b472b8..6d0ca3930 100644 --- a/relay/utils/get_current_network_config.ts +++ b/relay/utils/get_current_network_config.ts @@ -5,6 +5,7 @@ interface Config { NETWORK_NAME: string; BEACON_REST_API: string[]; SLOTS_PER_EPOCH: number; + SECONDS_PER_SLOT: number; EPOCHS_PER_SYNC_COMMITTEE_PERIOD: number; GENESIS_FORK_VERSION: string; FORK_VERSION: string; @@ -16,6 +17,7 @@ const defaultConfig: Config = { NETWORK_NAME: '', BEACON_REST_API: [], SLOTS_PER_EPOCH: 0, + SECONDS_PER_SLOT: 0, EPOCHS_PER_SYNC_COMMITTEE_PERIOD: 0, GENESIS_FORK_VERSION: '', FORK_VERSION: '', @@ -58,6 +60,7 @@ export async function getNetworkConfig( const config_genesis = await beaconApi.getGenesisData(); config.SLOTS_PER_EPOCH = Number(await beaconApi.getSlotsPerEpoch()); + config.SECONDS_PER_SLOT = Number(await beaconApi.getSecondsPerSlot()); config.EPOCHS_PER_SYNC_COMMITTEE_PERIOD = Number( await beaconApi.getSlotsPerSyncCommitteePeriod(), ); diff --git a/yarn-project.nix b/yarn-project.nix index 43162e690..655681739 100644 --- a/yarn-project.nix +++ b/yarn-project.nix @@ -130,61 +130,61 @@ let "bufferutil@npm:4.0.8" \ ${isolated."bufferutil@npm:4.0.8"} \ ".yarn/unplugged/bufferutil-npm-4.0.8-8005ed6210/node_modules/bufferutil" - echo 'injecting build for secp256k1' + echo 'injecting build for utf-8-validate' yarn nixify inject-build \ - "secp256k1@npm:4.0.3" \ - ${isolated."secp256k1@npm:4.0.3"} \ - ".yarn/unplugged/secp256k1-npm-4.0.3-b4e9ce065b/node_modules/secp256k1" + "utf-8-validate@npm:5.0.10" \ + ${isolated."utf-8-validate@npm:5.0.10"} \ + ".yarn/unplugged/utf-8-validate-npm-5.0.10-93e9b6f750/node_modules/utf-8-validate" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.4" \ ${isolated."keccak@npm:3.0.4"} \ ".yarn/unplugged/keccak-npm-3.0.4-a84763aab8/node_modules/keccak" - echo 'injecting build for utf-8-validate' + echo 'injecting build for secp256k1' yarn nixify inject-build \ - "utf-8-validate@npm:5.0.7" \ - ${isolated."utf-8-validate@npm:5.0.7"} \ - ".yarn/unplugged/utf-8-validate-npm-5.0.7-88d731f8ad/node_modules/utf-8-validate" - echo 'injecting build for utf-8-validate' + "secp256k1@npm:4.0.3" \ + ${isolated."secp256k1@npm:4.0.3"} \ + ".yarn/unplugged/secp256k1-npm-4.0.3-b4e9ce065b/node_modules/secp256k1" + echo 'injecting build for bcrypto' yarn nixify inject-build \ - "utf-8-validate@npm:5.0.10" \ - ${isolated."utf-8-validate@npm:5.0.10"} \ - ".yarn/unplugged/utf-8-validate-npm-5.0.10-93e9b6f750/node_modules/utf-8-validate" + "bcrypto@npm:5.5.2" \ + ${isolated."bcrypto@npm:5.5.2"} \ + ".yarn/unplugged/bcrypto-npm-5.5.2-f3838b92ce/node_modules/bcrypto" echo 'injecting build for blake-hash' yarn nixify inject-build \ "blake-hash@npm:2.0.0" \ ${isolated."blake-hash@npm:2.0.0"} \ ".yarn/unplugged/blake-hash-npm-2.0.0-c63b9a2c2d/node_modules/blake-hash" - echo 'injecting build for bufferutil' - yarn nixify inject-build \ - "bufferutil@npm:4.0.5" \ - ${isolated."bufferutil@npm:4.0.5"} \ - ".yarn/unplugged/bufferutil-npm-4.0.5-88cc521694/node_modules/bufferutil" - echo 'injecting build for leveldown' + echo 'injecting build for bcrypt' yarn nixify inject-build \ - "leveldown@npm:6.1.0" \ - ${isolated."leveldown@npm:6.1.0"} \ - ".yarn/unplugged/leveldown-npm-6.1.0-c2d7a4250d/node_modules/leveldown" + "bcrypt@npm:5.0.1" \ + ${isolated."bcrypt@npm:5.0.1"} \ + ".yarn/unplugged/bcrypt-npm-5.0.1-6815be1cfe/node_modules/bcrypt" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.1" \ ${isolated."keccak@npm:3.0.1"} \ ".yarn/unplugged/keccak-npm-3.0.1-9f0a714d5c/node_modules/keccak" + echo 'injecting build for bufferutil' + yarn nixify inject-build \ + "bufferutil@npm:4.0.5" \ + ${isolated."bufferutil@npm:4.0.5"} \ + ".yarn/unplugged/bufferutil-npm-4.0.5-88cc521694/node_modules/bufferutil" echo 'injecting build for keccak' yarn nixify inject-build \ "keccak@npm:3.0.2" \ ${isolated."keccak@npm:3.0.2"} \ ".yarn/unplugged/keccak-npm-3.0.2-6e9dec8765/node_modules/keccak" - echo 'injecting build for bcrypt' + echo 'injecting build for leveldown' yarn nixify inject-build \ - "bcrypt@npm:5.0.1" \ - ${isolated."bcrypt@npm:5.0.1"} \ - ".yarn/unplugged/bcrypt-npm-5.0.1-6815be1cfe/node_modules/bcrypt" - echo 'injecting build for bcrypto' + "leveldown@npm:6.1.0" \ + ${isolated."leveldown@npm:6.1.0"} \ + ".yarn/unplugged/leveldown-npm-6.1.0-c2d7a4250d/node_modules/leveldown" + echo 'injecting build for utf-8-validate' yarn nixify inject-build \ - "bcrypto@npm:5.5.2" \ - ${isolated."bcrypto@npm:5.5.2"} \ - ".yarn/unplugged/bcrypto-npm-5.5.2-f3838b92ce/node_modules/bcrypto" + "utf-8-validate@npm:5.0.7" \ + ${isolated."utf-8-validate@npm:5.0.7"} \ + ".yarn/unplugged/utf-8-validate-npm-5.0.7-88d731f8ad/node_modules/utf-8-validate" echo 'injecting build for redis-commander' yarn nixify inject-build \ "redis-commander@npm:0.8.0" \ @@ -249,16 +249,16 @@ let isolated."msgpackr-extract@npm:3.0.2" = optionalOverride (args.overrideMsgpackrExtractAttrs or null) (mkIsolatedBuild { pname = "msgpackr-extract"; version = "3.0.2"; reference = "npm:3.0.2"; }); isolated."bufferutil@npm:4.0.8" = optionalOverride (args.overrideBufferutilAttrs or null) (mkIsolatedBuild { pname = "bufferutil"; version = "4.0.8"; reference = "npm:4.0.8"; }); -isolated."secp256k1@npm:4.0.3" = optionalOverride (args.overrideSecp256k1Attrs or null) (mkIsolatedBuild { pname = "secp256k1"; version = "4.0.3"; reference = "npm:4.0.3"; }); -isolated."keccak@npm:3.0.4" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.4"; reference = "npm:3.0.4"; }); -isolated."utf-8-validate@npm:5.0.7" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.7"; reference = "npm:5.0.7"; }); isolated."utf-8-validate@npm:5.0.10" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.10"; reference = "npm:5.0.10"; }); +isolated."keccak@npm:3.0.4" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.4"; reference = "npm:3.0.4"; }); +isolated."secp256k1@npm:4.0.3" = optionalOverride (args.overrideSecp256k1Attrs or null) (mkIsolatedBuild { pname = "secp256k1"; version = "4.0.3"; reference = "npm:4.0.3"; }); +isolated."bcrypto@npm:5.5.2" = optionalOverride (args.overrideBcryptoAttrs or null) (mkIsolatedBuild { pname = "bcrypto"; version = "5.5.2"; reference = "npm:5.5.2"; }); isolated."blake-hash@npm:2.0.0" = optionalOverride (args.overrideBlakeHashAttrs or null) (mkIsolatedBuild { pname = "blake-hash"; version = "2.0.0"; reference = "npm:2.0.0"; }); -isolated."bufferutil@npm:4.0.5" = optionalOverride (args.overrideBufferutilAttrs or null) (mkIsolatedBuild { pname = "bufferutil"; version = "4.0.5"; reference = "npm:4.0.5"; }); -isolated."leveldown@npm:6.1.0" = optionalOverride (args.overrideLeveldownAttrs or null) (mkIsolatedBuild { pname = "leveldown"; version = "6.1.0"; reference = "npm:6.1.0"; }); +isolated."bcrypt@npm:5.0.1" = optionalOverride (args.overrideBcryptAttrs or null) (mkIsolatedBuild { pname = "bcrypt"; version = "5.0.1"; reference = "npm:5.0.1"; }); isolated."keccak@npm:3.0.1" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.1"; reference = "npm:3.0.1"; }); +isolated."bufferutil@npm:4.0.5" = optionalOverride (args.overrideBufferutilAttrs or null) (mkIsolatedBuild { pname = "bufferutil"; version = "4.0.5"; reference = "npm:4.0.5"; }); isolated."keccak@npm:3.0.2" = optionalOverride (args.overrideKeccakAttrs or null) (mkIsolatedBuild { pname = "keccak"; version = "3.0.2"; reference = "npm:3.0.2"; }); -isolated."bcrypt@npm:5.0.1" = optionalOverride (args.overrideBcryptAttrs or null) (mkIsolatedBuild { pname = "bcrypt"; version = "5.0.1"; reference = "npm:5.0.1"; }); -isolated."bcrypto@npm:5.5.2" = optionalOverride (args.overrideBcryptoAttrs or null) (mkIsolatedBuild { pname = "bcrypto"; version = "5.5.2"; reference = "npm:5.5.2"; }); +isolated."leveldown@npm:6.1.0" = optionalOverride (args.overrideLeveldownAttrs or null) (mkIsolatedBuild { pname = "leveldown"; version = "6.1.0"; reference = "npm:6.1.0"; }); +isolated."utf-8-validate@npm:5.0.7" = optionalOverride (args.overrideUtf8ValidateAttrs or null) (mkIsolatedBuild { pname = "utf-8-validate"; version = "5.0.7"; reference = "npm:5.0.7"; }); isolated."redis-commander@npm:0.8.0" = optionalOverride (args.overrideRedisCommanderAttrs or null) (mkIsolatedBuild { pname = "redis-commander"; version = "0.8.0"; reference = "npm:0.8.0"; }); in overriddenProject From 1aaa2f0846e98d9b814030b1e049bfdaedde0c9f Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Tue, 7 Jan 2025 12:46:59 +0200 Subject: [PATCH 08/12] fix: Increase node memory limit --- libs/nix/shell-with-light-client.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/nix/shell-with-light-client.nix b/libs/nix/shell-with-light-client.nix index d649e5f12..3448b04eb 100644 --- a/libs/nix/shell-with-light-client.nix +++ b/libs/nix/shell-with-light-client.nix @@ -12,7 +12,7 @@ in shellHook = '' set -e - export NODE_OPTIONS="--experimental-vm-modules --max-old-space-size=16384" + export NODE_OPTIONS="--experimental-vm-modules --max-old-space-size=131072" export PATH="$PATH:$PWD/node_modules/.bin"; export CC=clang export LOCAL_NIM_LIB="$PWD/vendor/nim/lib" From e80265bd737d5bf5ef632402c8ff0d8fbc7dde59 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Tue, 7 Jan 2025 15:18:38 +0200 Subject: [PATCH 09/12] fix: Constructor args genesis validators root --- beacon-light-client/solidity/tasks/utils/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-light-client/solidity/tasks/utils/index.ts b/beacon-light-client/solidity/tasks/utils/index.ts index f4ab4df2c..36297874c 100644 --- a/beacon-light-client/solidity/tasks/utils/index.ts +++ b/beacon-light-client/solidity/tasks/utils/index.ts @@ -18,7 +18,7 @@ export const getConstructorArgs = async ( let result = sha256( config.FORK_VERSION.padEnd(66, '0') + - config.GENESIS_VALIDATORS_ROOT.slice(2), + config.GENESIS_VALIDATORS_ROOT, ); return [ From b54c6761a34d72d9ad309ec4a48fcc08d51ad873 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Wed, 8 Jan 2025 11:51:33 +0200 Subject: [PATCH 10/12] fix: Fix explorer urls --- libs/typescript/ts-utils/evm.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/typescript/ts-utils/evm.ts b/libs/typescript/ts-utils/evm.ts index 71e0678fa..ee25c1579 100644 --- a/libs/typescript/ts-utils/evm.ts +++ b/libs/typescript/ts-utils/evm.ts @@ -1,4 +1,4 @@ -const networks = ['mainnet', 'sepolia', 'chiado', 'lukso'] as const; +const networks = ['homestead', 'sepolia', 'chiado', 'lukso', 'xdai'] as const; export type NetworkName = (typeof networks)[number]; @@ -43,7 +43,7 @@ export const txHash = (hexDataString: string): TxHash | null => { }; export const explorerUrls: Record = { - mainnet: { + homestead: { tx: txHash => `https://etherscan.io/tx/${txHash}`, address: address => `https://etherscan.io/address/${address}`, }, @@ -56,6 +56,10 @@ export const explorerUrls: Record = { address: address => `https://gnosis-chiado.blockscout.com/address/${address}`, }, + xdai: { + tx: txHash => `https://gnosisscan.io/tx/${txHash}`, + address: address => `https://gnosisscan.io/address/${address}`, + }, lukso: { tx: txHash => `https://explorer.consensus.testnet.lukso.network/tx/${txHash}`, From 6c60b60c8493d7365533b92f26c8fd7095c62cee Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Wed, 8 Jan 2025 13:36:07 +0200 Subject: [PATCH 11/12] fix: Stop retries when error is insufficient funds --- relay/on_chain_publisher.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/relay/on_chain_publisher.ts b/relay/on_chain_publisher.ts index 9978dc4f2..596dc05f7 100644 --- a/relay/on_chain_publisher.ts +++ b/relay/on_chain_publisher.ts @@ -96,7 +96,7 @@ export async function drainUpdatesInRedis( } isDrainRunning = true; let failedNumber = 0; - while (true) { + while (isDrainRunning) { try { const lastSlotOnChain = await getSlotOnChain(smartContract, beaconApi); @@ -241,6 +241,11 @@ async function handleFailure( scopeError: string, failedNumber: number, ): Promise<[number, boolean]> { + if (error.code === "INSUFFICIENT_FUNDS") { + log(error, `Insufficient funds in ${scopeError}`, 'STOPPING'); + isDrainRunning = false; + return [failedNumber, isDrainRunning]; + } if (failedNumber > 10) { log(error, `ERROR occurred in ${scopeError}`, 'STOPPING'); isDrainRunning = false; From f15ca7dc11df757eecdaf89f80868bdfbc916fd3 Mon Sep 17 00:00:00 2001 From: Dimo99 Date: Wed, 8 Jan 2025 14:55:28 +0200 Subject: [PATCH 12/12] fix: Discord monitor to work with light client directly --- relay/utils/discord_monitor.ts | 62 +++++++++++++++------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/relay/utils/discord_monitor.ts b/relay/utils/discord_monitor.ts index 731139151..755bb598a 100644 --- a/relay/utils/discord_monitor.ts +++ b/relay/utils/discord_monitor.ts @@ -1,45 +1,34 @@ import { ethers } from 'ethers'; import * as Discord from 'discord.js'; -import contractAbi from '../../beacon-light-client/solidity/tasks/hashi_abi.json'; +import contractAbi from '../../beacon-light-client/solidity/artifacts/contracts/bridge/src/truth/eth/BeaconLightClient.sol/BeaconLightClient.json'; import { getEnvString } from '@dendreth/utils/ts-utils/common-utils'; -async function getLastEventTime( +async function startStateMonitor( contract: ethers.Contract, - network: string, -): Promise { - const latestBlock = await contract.provider.getBlockNumber(); - const filter = contract.filters.HashStored(); - - const events = await contract.queryFilter( - filter, - latestBlock - 100000, - latestBlock, - ); - if (events.length === 0) { - console.log(`No events found for network '${network}'.`); - throw new Error('No events found.'); - } +): Promise<() => number> { + let lastKnownState = await contract.optimisticHeaderSlot(); + let lastUpdateTime = Date.now(); + + setInterval(async () => { + const currentState = await contract.optimisticHeaderSlot(); + if (currentState.toString() != lastKnownState.toString()) { + console.log(`State updated from ${lastKnownState} to ${currentState}`); + lastKnownState = currentState; + lastUpdateTime = Date.now(); + } + }, 60 * 1000); - return (await events[events.length - 1].getBlock()).timestamp * 1000; + return () => lastUpdateTime; } -// Monitor function that checks for contract updates and dispatches Discord alerts async function checkContractUpdate( - providerUrl: string, - contractAddress: string, + getLastUpdateTime: () => number, network: string, alertThresholdMinutes: number, discordClient: Discord.Client, ) { try { - const provider = new ethers.providers.JsonRpcProvider(providerUrl); - const contract = new ethers.Contract( - contractAddress, - contractAbi, - provider, - ); - - const lastEventTime = await getLastEventTime(contract, network); + const lastEventTime = getLastUpdateTime(); const delayInMinutes = (Date.now() - lastEventTime) / 1000 / 60; if (!discordClient.isReady()) { @@ -106,13 +95,19 @@ async function monitorContracts(networksAndAddresses: string[]) { try { const rpcUrl = getEnvString(`${network.toUpperCase()}_RPC`); + const provider = new ethers.providers.JsonRpcProvider(rpcUrl); + const contract = new ethers.Contract( + contractAddress, + contractAbi.abi, + provider, + ); networks.push(network); - // Immediately check the contract update, then set interval + const getLastUpdateTime = await startStateMonitor(contract); + checkContractUpdate( - rpcUrl, - contractAddress, + getLastUpdateTime, network, alertThresholdMinutes, discordClient, @@ -121,14 +116,13 @@ async function monitorContracts(networksAndAddresses: string[]) { setInterval( () => checkContractUpdate( - rpcUrl, - contractAddress, + getLastUpdateTime, network, alertThresholdMinutes, discordClient, ), 5 * 60 * 1000, - ); + ); // Check every 5 minutes } catch (error) { if (error instanceof Error) { console.warn(`Skipping network '${network}' due to:`, error.message);