diff --git a/.env.example b/.env.example index 0cec152fb..385ea2ff9 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,23 @@ -USER_PRIVATE_KEY=private_key -ALCHEMY_API_KEY=api_key +USER_PRIVATE_KEY_FILE=/.secrets/user_private_key +INFURA_API_KEY_FILE=/.secrets/infura_api_key +ALCHEMY_API_KEY_FILE=/.secrets/alchemy_api_key +ETHERSCAN_API_KEY_FILE=/.secrets/etherscan_api_key +BASE_ETHERSCAN_API_KEY_FILE=/.secrets/base_etherscan_api_key +POLYGON_MUMBAI_ETHERSCAN_API_KEY_FILE=/.secrets/polygon_mumbai_etherscan_api_key +POLYGON_ZK_ETHERSCAN_API_KEY_FILE=/.secrets/polygon_zk_etherscan_api_key +ARBITRUM_ETHERSCAN_API_KEY_FILE=/.secrets/arbitrum_etherscan_api_key +OPTIMISM_ETHERSCAN_API_KEY_FILE=/.secrets/optimism_etherscan_api_key +AVALANCHE_FUJI_ETHERSCAN_API_KEY_FILE=/.secrets/avalanche_fuji_etherscan_api_key +FTM_ETHERSCAN_API_KEY_FILE=/.secrets/ftm_etherscan_api_key +CELO_ETHERSCAN_API_KEY_FILE=/.secrets/celo_etherscan_api_key +BSC_ETHERSCAN_API_KEY_FILE=/.secrets/bsc_etherscan_api_key +CHIADO_ETHERSCAN_API_FILE=/.secrets/chiado_etherscan_api +GNOSIS_ETHERSCAN_API_FILE=/.secrets/gnosis_etherscan_api +BEACON_REST_API_PRATTER= +BEACON_REST_API_MAINNET= +BEACON_REST_API_SEPOLIA= +BEACON_REST_API_CHIADO= +BEACON_REST_API_GNOSIS= REDIS_HOST=localhost REDIS_PORT=6379 PROVER_SERVER_HOST=http://127.0.0.1 @@ -13,6 +31,7 @@ LC_OPTIMISTIC_GOERLI= LC_BASE_GOERLI= LC_ARBITRUM_GOERLI= LC_SEPOLIA= +FOLLOW_NETWORK_SEPOLIA=chiado LC_MUMBAI= LC_FUJI= LC_FANTOM= @@ -21,9 +40,15 @@ LC_BSC= LC_AURORA= LC_GNOSIS= LC_CHIADO= +FOLLOW_NETWORK_CHIADO=sepolia LC_EVMOS= LC_MALAGA= +LC_LUKSO= +FOLLOW_NETWORK_LUKSO=sepolia GOERLI_HASHI=0x4169ea397fe83F55e732E11390807b3722374f78 +MAINNET_HASHI= +FOLLOW_NETWORK_MAINNET= +FOLLOW_NETWORK_GNOSIS= OPTIMISTIC_HASHI='' BASE_HASHI='' ARBITRUM_HASHI='' @@ -38,3 +63,21 @@ AURORA_HASHI='' GNOSIS_HASHI='' FUJI_HASHI='' BSC_HASHI='' +LUKSO_HASHI='' +MAINNET_RPC= +ROPSTEN_RPC= +SEPOLIA_RPC= +GOERLI_RPC= +OPTIMISTIC_GOERLI_RPC= +BASE_GOERLI_RPC= +ARBITRUM_GOERLI_RPC= +MUMBAI_RPC= +AVALANCHE_RPC= +FANTOM_RPC= +CELO_RPC= +BSC_RPC= +CHIADO_RPC= +GNOSIS_RPC= +EVMOS_RPC= +AURORA_RPC= +LUKSO_RPC= diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5be585cbd..a952de828 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ env: INFURA_API_KEY: '${{ secrets.INFURA_API_KEY }}' USER_PRIVATE_KEY: '${{ secrets.USER_PRIVATE_KEY }}' ETHERSCAN_API_KEY: '${{ secrets.ETHERSCAN_API_KEY }}' - ETHEREUM_MAINNET_RPC: https://eth.llamarpc.com + MAINNET_RPC: https://rpc.mevblocker.io jobs: Linter: runs-on: self-hosted diff --git a/.gitmodules b/.gitmodules index 8c360099e..b5028cdc6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -57,4 +57,4 @@ url = https://github.com/ethereum/consensus-spec-tests.git [submodule "vendor/snarkjs"] path = vendor/snarkjs - url = git@github.com:iden3/snarkjs.git + url = git@github.com:metacraft-labs/snarkjs.git 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 4363d0036..2e1721630 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/interfaces/ILightClient.sol @@ -2,21 +2,35 @@ pragma solidity 0.8.9; interface ILightClient { - function currentIndex() external view returns (uint256); + struct LightClientUpdate { + bytes32 attestedHeaderRoot; + uint256 attestedHeaderSlot; + bytes32 finalizedHeaderRoot; + bytes32 finalizedExecutionStateRoot; + uint256[2] a; + uint256[2][2] b; + uint256[2] c; + } - function optimisticHeaderRoot() external view returns (bytes32); + function currentIndex() external view returns (uint256); - function optimisticHeaderSlot() external view returns (uint256); + function optimisticHeaderRoot() external view returns (bytes32); - function finalizedHeaderRoot() external view returns (bytes32); + function optimisticHeaderSlot() external view returns (uint256); - function executionStateRoot() external view returns (bytes32); + function finalizedHeaderRoot() external view returns (bytes32); - function optimisticHeaders(uint256 index) external view returns (bytes32); + function executionStateRoot() external view returns (bytes32); - function optimisticSlots(uint256 index) external view returns (uint256); + function optimisticHeaders(uint256 index) external view returns (bytes32); - function finalizedHeaders(uint256 index) external view returns (bytes32); + function optimisticSlots(uint256 index) external view returns (uint256); - function executionStateRoots(uint256 index) external view returns (bytes32); + function finalizedHeaders(uint256 index) external view returns (bytes32); + + function executionStateRoots(uint256 index) external view returns (bytes32); + + function lightClientUpdate( + LightClientUpdate calldata update + ) external payable; } 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 144d01b52..ad13442f8 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 @@ -7,16 +7,6 @@ import '../../interfaces/ILightClient.sol'; uint256 constant BUFER_SIZE = 32; contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { - struct LightClientUpdate { - bytes32 attestedHeaderRoot; - uint256 attestedHeaderSlot; - bytes32 finalizedHeaderRoot; - bytes32 finalizedExecutionStateRoot; - uint256[2] a; - uint256[2][2] b; - uint256[2] c; - } - bytes32[BUFER_SIZE] public optimisticHeaders; uint256[BUFER_SIZE] public optimisticSlots; @@ -62,7 +52,7 @@ contract BeaconLightClient is LightClientUpdateVerifier, ILightClient { } // TODO: fix name to lightClientUpdate - function light_client_update(LightClientUpdate calldata update) + function lightClientUpdate(LightClientUpdate calldata update) external payable { 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 13bda070b..76629582f 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/utils/LightClientUpdateVerifier.sol @@ -3,7 +3,9 @@ pragma solidity 0.8.9; import './Verifier.sol'; -contract LightClientUpdateVerifier is Verifier { +contract LightClientUpdateVerifier is Groth16Verifier { + error VerificationCallFailed(); + function verifyUpdate( uint256[2] memory a, uint256[2][2] memory b, @@ -14,7 +16,7 @@ contract LightClientUpdateVerifier is Verifier { bytes32 finalizedHeaderRoot, bytes32 executionStateRoot, bytes32 domain - ) internal view returns (bool) { + ) internal returns (bool) { bytes memory concatenated = abi.encodePacked(prevHeaderHash, nextHeaderHash, finalizedHeaderRoot, executionStateRoot, nextHeaderSlot, domain); bytes32 commitment = sha256(concatenated); @@ -23,6 +25,16 @@ contract LightClientUpdateVerifier is Verifier { input[0] = (uint256(commitment) & (((1 << 253) - 1) << 3)) >> 3; input[1] = (uint256(commitment) & ((1 << 3) - 1)); - return verifyProof(a, b, c, input); + (bool success, bytes memory returnData) = address(this).call( + // Encode the call to the `verify` function with the public inputs + abi.encodeWithSelector(Groth16Verifier.verifyProof.selector, a, b, c, input) + ); + + // Check if the call was successful + if (!success) { + revert VerificationCallFailed(); + } + + return abi.decode(returnData, (bool)); } } 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 f33b7489e..0f0c5ae4e 100644 --- a/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol +++ b/beacon-light-client/solidity/contracts/bridge/src/utils/Verifier.sol @@ -1,260 +1,177 @@ -// -// Copyright 2017 Christian Reitwiessner -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// 2019 OKIMS -// ported to solidity 0.6 -// fixed linter warnings -// added requiere error messages -// -// // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.9; -library Pairing { - struct G1Point { - uint X; - uint Y; - } - // Encoding of field elements is: X[0] * z + X[1] - struct G2Point { - uint[2] X; - uint[2] Y; - } - /// @return the generator of G1 - function P1() internal pure returns (G1Point memory) { - return G1Point(1, 2); - } - /// @return the generator of G2 - function P2() internal pure returns (G2Point memory) { - // Original code point - return G2Point( - [11559732032986387107991004021392285783925812861821192530917403151452391805634, - 10857046999023057135944570762232829481370756359578518086990519993285655852781], - [4082367875863433681332203403145435568316851327593401208105741076214120093531, - 8495653923123431417604973247489272438418190587263600148770280649306958101930] - ); - /* - // Changed by Jordi point - return G2Point( - [10857046999023057135944570762232829481370756359578518086990519993285655852781, - 11559732032986387107991004021392285783925812861821192530917403151452391805634], - [8495653923123431417604973247489272438418190587263600148770280649306958101930, - 4082367875863433681332203403145435568316851327593401208105741076214120093531] - ); + Copyright 2021 0KIMS association. + + This file is generated with [snarkJS](https://github.com/iden3/snarkjs). + + snarkJS is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + snarkJS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with snarkJS. If not, see . */ - } - /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero. - function negate(G1Point memory p) internal pure returns (G1Point memory r) { - // The prime q in the base field F_q for G1 - uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; - if (p.X == 0 && p.Y == 0) - return G1Point(0, 0); - return G1Point(p.X, q - (p.Y % q)); - } - /// @return r the sum of two points of G1 - function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) { - uint[4] memory input; - input[0] = p1.X; - input[1] = p1.Y; - input[2] = p2.X; - input[3] = p2.Y; - bool success; - // solium-disable-next-line security/no-inline-assembly - assembly { - success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } - require(success,"pairing-add-failed"); - } - /// @return r the product of a point on G1 and a scalar, i.e. - /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p. - function scalar_mul(G1Point memory p, uint s) internal view returns (G1Point memory r) { - uint[3] memory input; - input[0] = p.X; - input[1] = p.Y; - input[2] = s; - bool success; - // solium-disable-next-line security/no-inline-assembly - assembly { - success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } - require (success,"pairing-mul-failed"); - } - /// @return the result of computing the pairing check - /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 - /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should - /// return true. - function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) { - require(p1.length == p2.length,"pairing-lengths-failed"); - uint elements = p1.length; - uint inputSize = elements * 6; - uint[] memory input = new uint[](inputSize); - for (uint i = 0; i < elements; i++) - { - input[i * 6 + 0] = p1[i].X; - input[i * 6 + 1] = p1[i].Y; - input[i * 6 + 2] = p2[i].X[0]; - input[i * 6 + 3] = p2[i].X[1]; - input[i * 6 + 4] = p2[i].Y[0]; - input[i * 6 + 5] = p2[i].Y[1]; - } - uint[1] memory out; - bool success; - // solium-disable-next-line security/no-inline-assembly + +pragma solidity >=0.7.0 <0.9.0; + +contract Groth16Verifier { + // Scalar field size + uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + // Base field size + uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + + // Verification Key data + uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; + uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; + uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; + uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; + uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; + uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; + uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; + 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 IC0x = 15885245864077738868080438953982725331851392259561989715709451737775650751499; + uint256 constant IC0y = 3058542624047584215597339891062268073059023573536176596654360197630215303398; + + uint256 constant IC1x = 3255066205384872240945589813541061230086894640948769948284130216055868495482; + uint256 constant IC1y = 16460914464567897526651674410663529211360506782549350639411464298117968849205; + + uint256 constant IC2x = 11064230506301119445251518703398711794668854432878025946021783974855346283581; + uint256 constant IC2y = 21566276678649624161455346253569989476836415222383483939094883480794570252979; + + + // Memory data + uint16 constant pVk = 0; + uint16 constant pPairing = 128; + + uint16 constant pLastMem = 896; + + function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public view returns (bool) { assembly { - success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) - // Use "invalid" to make gas estimation work - switch success case 0 { invalid() } - } - require(success,"pairing-opcode-failed"); - return out[0] != 0; - } - /// Convenience method for a pairing check for two pairs. - function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal view returns (bool) { - G1Point[] memory p1 = new G1Point[](2); - G2Point[] memory p2 = new G2Point[](2); - p1[0] = a1; - p1[1] = b1; - p2[0] = a2; - p2[1] = b2; - return pairing(p1, p2); - } - /// Convenience method for a pairing check for three pairs. - function pairingProd3( - G1Point memory a1, G2Point memory a2, - G1Point memory b1, G2Point memory b2, - G1Point memory c1, G2Point memory c2 - ) internal view returns (bool) { - G1Point[] memory p1 = new G1Point[](3); - G2Point[] memory p2 = new G2Point[](3); - p1[0] = a1; - p1[1] = b1; - p1[2] = c1; - p2[0] = a2; - p2[1] = b2; - p2[2] = c2; - return pairing(p1, p2); - } - /// Convenience method for a pairing check for four pairs. - function pairingProd4( - G1Point memory a1, G2Point memory a2, - G1Point memory b1, G2Point memory b2, - G1Point memory c1, G2Point memory c2, - G1Point memory d1, G2Point memory d2 - ) internal view returns (bool) { - G1Point[] memory p1 = new G1Point[](4); - G2Point[] memory p2 = new G2Point[](4); - p1[0] = a1; - p1[1] = b1; - p1[2] = c1; - p1[3] = d1; - p2[0] = a2; - p2[1] = b2; - p2[2] = c2; - p2[3] = d2; - return pairing(p1, p2); - } -} -contract Verifier { - using Pairing for *; - struct VerifyingKey { - Pairing.G1Point alfa1; - Pairing.G2Point beta2; - Pairing.G2Point gamma2; - Pairing.G2Point delta2; - Pairing.G1Point[] IC; - } - struct Proof { - Pairing.G1Point A; - Pairing.G2Point B; - Pairing.G1Point C; - } - function verifyingKey() internal pure returns (VerifyingKey memory vk) { - vk.alfa1 = Pairing.G1Point( - 20491192805390485299153009773594534940189261866228447918068658471970481763042, - 9383485363053290200918347156157836566562967994039712273449902621266178545958 - ); - - vk.beta2 = Pairing.G2Point( - [4252822878758300859123897981450591353533073413197771768651442665752259397132, - 6375614351688725206403948262868962793625744043794305715222011528459656738731], - [21847035105528745403288232691147584728191162732299865338377159692350059136679, - 10505242626370262277552901082094356697409835680220590971873171140371331206856] - ); - vk.gamma2 = Pairing.G2Point( - [11559732032986387107991004021392285783925812861821192530917403151452391805634, - 10857046999023057135944570762232829481370756359578518086990519993285655852781], - [4082367875863433681332203403145435568316851327593401208105741076214120093531, - 8495653923123431417604973247489272438418190587263600148770280649306958101930] - ); - vk.delta2 = Pairing.G2Point( - [11559732032986387107991004021392285783925812861821192530917403151452391805634, - 10857046999023057135944570762232829481370756359578518086990519993285655852781], - [4082367875863433681332203403145435568316851327593401208105741076214120093531, - 8495653923123431417604973247489272438418190587263600148770280649306958101930] - ); - vk.IC = new Pairing.G1Point[](3); - - vk.IC[0] = Pairing.G1Point( - 15885245864077738868080438953982725331851392259561989715709451737775650751499, - 3058542624047584215597339891062268073059023573536176596654360197630215303398 - ); - - vk.IC[1] = Pairing.G1Point( - 3255066205384872240945589813541061230086894640948769948284130216055868495482, - 16460914464567897526651674410663529211360506782549350639411464298117968849205 - ); - - vk.IC[2] = Pairing.G1Point( - 11064230506301119445251518703398711794668854432878025946021783974855346283581, - 21566276678649624161455346253569989476836415222383483939094883480794570252979 - ); - - } - function verify(uint[] memory input, Proof memory proof) internal view returns (uint) { - uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - VerifyingKey memory vk = verifyingKey(); - require(input.length + 1 == vk.IC.length,"verifier-bad-input"); - // Compute the linear combination vk_x - Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); - for (uint i = 0; i < input.length; i++) { - require(input[i] < snark_scalar_field,"verifier-gte-snark-scalar-field"); - vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i])); - } - vk_x = Pairing.addition(vk_x, vk.IC[0]); - if (!Pairing.pairingProd4( - Pairing.negate(proof.A), proof.B, - vk.alfa1, vk.beta2, - vk_x, vk.gamma2, - proof.C, vk.delta2 - )) return 1; - return 0; - } - /// @return r bool true if proof is valid - function verifyProof( - uint[2] memory a, - uint[2][2] memory b, - uint[2] memory c, - uint[2] memory input - ) public view returns (bool r) { - Proof memory proof; - proof.A = Pairing.G1Point(a[0], a[1]); - proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]); - proof.C = Pairing.G1Point(c[0], c[1]); - uint[] memory inputValues = new uint[](input.length); - for(uint i = 0; i < input.length; i++){ - inputValues[i] = input[i]; - } - if (verify(inputValues, proof) == 0) { - return true; - } else { - return false; - } - } -} + function checkField(v) { + if iszero(lt(v, r)) { + mstore(0, 0) + return(0, 0x20) + } + } + + // G1 function to multiply a G1 value(x,y) to value in an address + function g1_mulAccC(pR, x, y, s) { + let success + let mIn := mload(0x40) + mstore(mIn, x) + mstore(add(mIn, 32), y) + mstore(add(mIn, 64), s) + + success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + + mstore(add(mIn, 64), mload(pR)) + mstore(add(mIn, 96), mload(add(pR, 32))) + + success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + } + + function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { + let _pPairing := add(pMem, pPairing) + let _pVk := add(pMem, pVk) + + mstore(_pVk, IC0x) + mstore(add(_pVk, 32), IC0y) + + // Compute the linear combination vk_x + + g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) + + g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) + + + // -A + mstore(_pPairing, calldataload(pA)) + mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) + + // B + mstore(add(_pPairing, 64), calldataload(pB)) + mstore(add(_pPairing, 96), calldataload(add(pB, 32))) + mstore(add(_pPairing, 128), calldataload(add(pB, 64))) + mstore(add(_pPairing, 160), calldataload(add(pB, 96))) + + // alpha1 + mstore(add(_pPairing, 192), alphax) + mstore(add(_pPairing, 224), alphay) + + // beta2 + mstore(add(_pPairing, 256), betax1) + mstore(add(_pPairing, 288), betax2) + mstore(add(_pPairing, 320), betay1) + mstore(add(_pPairing, 352), betay2) + + // vk_x + mstore(add(_pPairing, 384), mload(add(pMem, pVk))) + mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) + + + // gamma2 + mstore(add(_pPairing, 448), gammax1) + mstore(add(_pPairing, 480), gammax2) + mstore(add(_pPairing, 512), gammay1) + mstore(add(_pPairing, 544), gammay2) + + // C + mstore(add(_pPairing, 576), calldataload(pC)) + mstore(add(_pPairing, 608), calldataload(add(pC, 32))) + + // delta2 + mstore(add(_pPairing, 640), deltax1) + mstore(add(_pPairing, 672), deltax2) + mstore(add(_pPairing, 704), deltay1) + mstore(add(_pPairing, 736), deltay2) + + + let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) + + isOk := and(success, mload(_pPairing)) + } + + let pMem := mload(0x40) + mstore(0x40, add(pMem, pLastMem)) + + // Validate that all evaluations ∈ F + + checkField(calldataload(add(_pubSignals, 0))) + + checkField(calldataload(add(_pubSignals, 32))) + + checkField(calldataload(add(_pubSignals, 64))) + + + // Validate all evaluations + let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) + + mstore(0, isValid) + return(0, 0x20) + } + } + } diff --git a/beacon-light-client/solidity/hardhat.config.ts b/beacon-light-client/solidity/hardhat.config.ts index bac831b1a..7d2e03c61 100644 --- a/beacon-light-client/solidity/hardhat.config.ts +++ b/beacon-light-client/solidity/hardhat.config.ts @@ -44,7 +44,7 @@ const conf = { '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', INFURA_API_KEY: getSecretEnvString('INFURA_API_KEY_FILE'), ETHERSCAN_API_KEY: getSecretEnvString('ETHERSCAN_API_KEY_FILE'), - ETHEREUM_MAINNET_RPC: process.env.ETHEREUM_MAINNET_RPC || '', + MAINNET_RPC: process.env.MAINNET_RPC || '', ROPSTEN_RPC: process.env.ROPSTEN_RPC || '', SEPOLIA_RPC: process.env.SEPOLIA_RPC || '', GOERLI_RPC: process.env.GOERLI_RPC || '', @@ -113,10 +113,14 @@ export default { }, hardhat: { forking: { - url: conf.ETHEREUM_MAINNET_RPC, + url: conf.MAINNET_RPC, blockNumber: 19931139, }, }, + mainnet: { + url: conf.MAINNET_RPC, + accounts: [conf.USER_PRIVATE_KEY], + }, ropsten: { url: conf.ROPSTEN_RPC, accounts: [conf.USER_PRIVATE_KEY], @@ -196,15 +200,23 @@ export default { baseGoerli: conf.BASE_ETHERSCAN_API_KEY, sepolia: conf.ETHERSCAN_API_KEY, goerli: conf.ETHERSCAN_API_KEY, + mainnet: conf.ETHERSCAN_API_KEY, avalancheFujiTestnet: conf.AVALANCHE_FUJI_ETHERSCAN_API_KEY, ftmTestnet: conf.FTM_ETHERSCAN_API_KEY, celo: conf.CELO_ETHERSCAN_API_KEY, bscTestnet: conf.BSC_ETHERSCAN_API_KEY, chiado: conf.CHIADO_ETHERSCAN_API, gnosis: conf.GNOSIS_ETHERSCAN_API, - lukso: conf.ETHERSCAN_API_KEY, }, customChains: [ + { + network: 'chiado', + chainId: 10200, + urls: { + apiURL: 'https://gnosis-chiado.blockscout.com/api', + browserURL: 'https://gnosis-chiado.blockscout.com/', + }, + }, { network: 'baseGoerli', chainId: 84531, diff --git a/beacon-light-client/solidity/tasks/balance-verifier-publisher.ts b/beacon-light-client/solidity/tasks/balance-verifier-publisher.ts index 35a8b016b..fb6ca0333 100644 --- a/beacon-light-client/solidity/tasks/balance-verifier-publisher.ts +++ b/beacon-light-client/solidity/tasks/balance-verifier-publisher.ts @@ -49,8 +49,8 @@ task('balance-verifier-publisher', 'Run relayer') ) .setAction(async (args, { ethers, network }) => { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); diff --git a/beacon-light-client/solidity/tasks/deploy-balance-verifier.ts b/beacon-light-client/solidity/tasks/deploy-balance-verifier.ts index b1ca34d81..4cf668004 100644 --- a/beacon-light-client/solidity/tasks/deploy-balance-verifier.ts +++ b/beacon-light-client/solidity/tasks/deploy-balance-verifier.ts @@ -38,8 +38,8 @@ task('deploy-balance-verifier', 'Deploy the beacon light client contract') let VERIFIER_DIGEST = args.verifierDigest; if (!VERIFIER_DIGEST) { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); diff --git a/beacon-light-client/solidity/tasks/deploy.ts b/beacon-light-client/solidity/tasks/deploy.ts index ad31b84c6..3a00ed7a5 100644 --- a/beacon-light-client/solidity/tasks/deploy.ts +++ b/beacon-light-client/solidity/tasks/deploy.ts @@ -1,7 +1,10 @@ import { task } from 'hardhat/config'; import { getBeaconApi } from '@dendreth/relay/implementations/beacon-api'; import { getConstructorArgs } from './utils'; -import { getNetworkConfig } from '@dendreth/relay/utils/get_current_network_config'; +import { + getNetworkConfig, + isSupportedFollowNetwork, +} from '@dendreth/relay/utils/get_current_network_config'; import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; const logger = getGenericLogger(); @@ -10,12 +13,7 @@ task('deploy', 'Deploy the beacon light client contract') .addParam('slot', 'The slot ') .addParam('followNetwork', 'The network to follow') .setAction(async (args, { run, ethers }) => { - if ( - args.followNetwork !== 'pratter' && - args.followNetwork !== 'mainnet' && - args.followNetwork !== 'sepolia' && - args.followNetwork !== 'chiado' - ) { + if (!isSupportedFollowNetwork(args.followNetwork)) { logger.warn('This followNetwork is not specified in networkconfig'); return; } diff --git a/beacon-light-client/solidity/tasks/hashi_abi.json b/beacon-light-client/solidity/tasks/hashi_abi.json index 7ea154ed9..7b223e13f 100644 --- a/beacon-light-client/solidity/tasks/hashi_abi.json +++ b/beacon-light-client/solidity/tasks/hashi_abi.json @@ -3,23 +3,22 @@ "inputs": [ { "internalType": "address", - "name": "_dendrETHAddress", + "name": "dendrETHAddress", "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ + }, { "internalType": "uint256", - "name": "slot", + "name": "sourceChainId", "type": "uint256" + }, + { + "internalType": "address", + "name": "sourceYaho", + "type": "address" } ], - "name": "BlockHeaderNotAvailable", - "type": "error" + "stateMutability": "nonpayable", + "type": "constructor" }, { "inputs": [ @@ -30,7 +29,7 @@ }, { "internalType": "bytes32", - "name": "reportedBlockHash", + "name": "blockHash", "type": "bytes32" }, { @@ -42,6 +41,22 @@ "name": "ConflictingBlockHeader", "type": "error" }, + { + "inputs": [], + "name": "ErrorParseReceipt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "finalizedHeader", + "type": "bytes32" + } + ], + "name": "FinalizedBlockHeaderNotAvailable", + "type": "error" + }, { "inputs": [], "name": "InvalidBlockHashProof", @@ -68,6 +83,21 @@ "name": "InvalidBlockNumberProof", "type": "error" }, + { + "inputs": [], + "name": "InvalidEventSignature", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidEventSource", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidReceiptsRoot", + "type": "error" + }, { "inputs": [], "name": "InvalidSlot", @@ -75,7 +105,7 @@ }, { "inputs": [], - "name": "InvalidUpdate", + "name": "UnsupportedTxType", "type": "error" }, { @@ -90,7 +120,7 @@ { "indexed": true, "internalType": "bytes32", - "name": "hashes", + "name": "hash", "type": "bytes32" } ], @@ -99,7 +129,7 @@ }, { "inputs": [], - "name": "dendrETHAddress", + "name": "DENDRETH_ADDRESS", "outputs": [ { "internalType": "address", @@ -111,24 +141,26 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "domain", - "type": "uint256" - }, + "inputs": [], + "name": "SOURCE_CHAIN_ID", + "outputs": [ { "internalType": "uint256", - "name": "id", + "name": "", "type": "uint256" } ], - "name": "getHashFromOracle", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SOURCE_YAHO", "outputs": [ { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" + "internalType": "address", + "name": "", + "type": "address" } ], "stateMutability": "view", @@ -138,16 +170,16 @@ "inputs": [ { "internalType": "uint256", - "name": "", + "name": "domain", "type": "uint256" }, { "internalType": "uint256", - "name": "", + "name": "id", "type": "uint256" } ], - "name": "hashes", + "name": "getHash", "outputs": [ { "internalType": "bytes32", @@ -179,38 +211,56 @@ { "inputs": [ { - "internalType": "uint32", - "name": "_chainId", - "type": "uint32" + "internalType": "bytes32", + "name": "finalizedBlockHeader", + "type": "bytes32" }, { - "internalType": "uint64", - "name": "_slot", - "type": "uint64" + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" }, { "internalType": "bytes32[]", - "name": "_slotProof", + "name": "blockNumberProof", "type": "bytes32[]" }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "blockHashProof", + "type": "bytes32[]" + } + ], + "name": "storeBlockHeader", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", - "name": "_blockNumber", + "name": "blockNumber", "type": "uint256" }, { "internalType": "bytes32[]", - "name": "_blockNumberProof", + "name": "blockNumberProof", "type": "bytes32[]" }, { "internalType": "bytes32", - "name": "_blockHash", + "name": "blockHash", "type": "bytes32" }, { "internalType": "bytes32[]", - "name": "_blockHashProof", + "name": "blockHashProof", "type": "bytes32[]" }, { @@ -264,47 +314,52 @@ { "inputs": [ { - "internalType": "uint32", - "name": "_chainId", - "type": "uint32" + "internalType": "bytes32", + "name": "srcFinalizedHeader", + "type": "bytes32" }, { "internalType": "uint64", - "name": "_slot", + "name": "srcSlot", "type": "uint64" }, { "internalType": "bytes32[]", - "name": "_slotProof", + "name": "slotProof", "type": "bytes32[]" }, { - "internalType": "bytes32", - "name": "_finalizedBlockHeader", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_blockNumber", - "type": "uint256" + "internalType": "uint64", + "name": "txSlot", + "type": "uint64" }, { "internalType": "bytes32[]", - "name": "_blockNumberProof", + "name": "receiptsRootProof", "type": "bytes32[]" }, { "internalType": "bytes32", - "name": "_blockHash", + "name": "receiptsRoot", "type": "bytes32" }, { - "internalType": "bytes32[]", - "name": "_blockHashProof", - "type": "bytes32[]" + "internalType": "bytes[]", + "name": "receiptProof", + "type": "bytes[]" + }, + { + "internalType": "bytes", + "name": "txIndexRLPEncoded", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "logIndex", + "type": "uint256" } ], - "name": "storeBlockHeader", + "name": "verifyAndStoreDispatchedMessage", "outputs": [], "stateMutability": "nonpayable", "type": "function" diff --git a/beacon-light-client/solidity/tasks/remove-repeat-job.ts b/beacon-light-client/solidity/tasks/remove-repeat-job.ts index d7e0bf778..573c55009 100644 --- a/beacon-light-client/solidity/tasks/remove-repeat-job.ts +++ b/beacon-light-client/solidity/tasks/remove-repeat-job.ts @@ -11,8 +11,8 @@ task('remove-repeat-job', 'Run update recuring task') .addParam('jobKey', 'The job key') .setAction(async args => { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); diff --git a/beacon-light-client/solidity/tasks/start-publishing.ts b/beacon-light-client/solidity/tasks/start-publishing.ts index 12ab8a378..08123dc9f 100644 --- a/beacon-light-client/solidity/tasks/start-publishing.ts +++ b/beacon-light-client/solidity/tasks/start-publishing.ts @@ -6,7 +6,10 @@ import { publishProofs } from '@dendreth/relay/on_chain_publisher'; import { checkConfig } from '@dendreth/utils/ts-utils/common-utils'; import { Contract, ethers } from 'ethers'; import hashi_abi from './hashi_abi.json'; -import { getNetworkConfig } from '@dendreth/relay/utils/get_current_network_config'; +import { + getNetworkConfig, + isSupportedFollowNetwork, +} from '@dendreth/relay/utils/get_current_network_config'; import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; import { initPrometheusSetup } from '@dendreth/utils/ts-utils/prometheus-utils'; @@ -46,18 +49,13 @@ task('start-publishing', 'Run relayer') ) .setAction(async (args, { ethers, network }) => { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); - if ( - args.followNetwork !== 'pratter' && - args.followNetwork !== 'mainnet' && - args.followNetwork !== 'sepolia' && - args.followNetwork !== 'chiado' - ) { + if (!isSupportedFollowNetwork(args.followNetwork)) { logger.warn('This followNetwork is not specified in networkconfig'); return; } @@ -68,7 +66,7 @@ task('start-publishing', 'Run relayer') let networkName: string = ''; for (let i = 0; i < process.argv.length; i++) { const arg = process.argv[i]; - if (arg === '--network' && i + 1 < process.argv.length) { + if (arg === '--follow-network' && i + 1 < process.argv.length) { networkName = process.argv[i + 1]; break; } diff --git a/beacon-light-client/solidity/tasks/utils/index.ts b/beacon-light-client/solidity/tasks/utils/index.ts index 30c01905f..f4ab4df2c 100644 --- a/beacon-light-client/solidity/tasks/utils/index.ts +++ b/beacon-light-client/solidity/tasks/utils/index.ts @@ -1,6 +1,7 @@ import { sha256 } from 'ethers/lib/utils'; import { IBeaconApi } from '@dendreth/relay/abstraction/beacon-api-interface'; import { Config } from '@dendreth/relay/constants/constants'; +import { bytesToHex } from '@dendreth/utils/ts-utils/bls'; export const getConstructorArgs = async ( beaconApi: IBeaconApi, @@ -21,9 +22,9 @@ export const getConstructorArgs = async ( ); return [ - finalizedHeaderRoot, + '0x' + bytesToHex(finalizedHeaderRoot), finalizedBlockHeader.slot, - finalizedHeaderRoot, + '0x' + bytesToHex(finalizedHeaderRoot), executioStateRoot, config.DOMAIN_SYNC_COMMITTEE + result.slice(2, 58), ]; diff --git a/beacon-light-client/solidity/tasks/verify-contracts.ts b/beacon-light-client/solidity/tasks/verify-contracts.ts index 791110596..4845960b6 100644 --- a/beacon-light-client/solidity/tasks/verify-contracts.ts +++ b/beacon-light-client/solidity/tasks/verify-contracts.ts @@ -1,7 +1,10 @@ import { task } from 'hardhat/config'; import { getBeaconApi } from '@dendreth/relay/implementations/beacon-api'; import { getConstructorArgs } from './utils'; -import { getNetworkConfig } from '@dendreth/relay/utils/get_current_network_config'; +import { + getNetworkConfig, + isSupportedFollowNetwork, +} from '@dendreth/relay/utils/get_current_network_config'; import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; const logger = getGenericLogger(); @@ -11,12 +14,7 @@ task('verify-contracts', 'Verify') .addParam('slot', 'The slot ') .addParam('followNetwork', 'The network to follow') .setAction(async (args, { run }) => { - if ( - args.followNetwork !== 'pratter' && - args.followNetwork !== 'mainnet' && - args.followNetwork !== 'sepolia' && - args.followNetwork !== 'chiado' - ) { + if (!isSupportedFollowNetwork(args.followNetwork)) { logger.warn('This followNetwork is not specified in networkconfig'); return; } @@ -25,6 +23,8 @@ task('verify-contracts', 'Verify') const beaconApi = await getBeaconApi(currentConfig.BEACON_REST_API!); + console.log(await getConstructorArgs(beaconApi, args.slot, currentConfig)); + await run('verify:verify', { address: args.lightClient, constructorArguments: await getConstructorArgs( diff --git a/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts b/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts index 29e83ac9c..8e028b174 100644 --- a/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts +++ b/beacon-light-client/solidity/test/BeaconLightClientReadyProofs.test.ts @@ -69,7 +69,7 @@ describe('BeaconLightClientReadyProofs', async function () { logger.info(` >>> Importing update ${i}...`); - const transaction = await blc.light_client_update( + const transaction = await blc.lightClientUpdate( { ...proof, ...updates[i] }, { gasLimit: 30000000, diff --git a/beacon-light-client/solidity/tsconfig.json b/beacon-light-client/solidity/tsconfig.json index cbd5af417..33e3969df 100644 --- a/beacon-light-client/solidity/tsconfig.json +++ b/beacon-light-client/solidity/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../../tsconfig.hardhat.json", "files": [ - "./hardhat.config.ts" + "./hardhat.config.ts", + "tasks/hashi_abi.json" ], "include": [ "./tasks", diff --git a/contracts/cosmos/scripts/cosmos-publisher-script.ts b/contracts/cosmos/scripts/cosmos-publisher-script.ts index 4fb0973fb..140e631c5 100644 --- a/contracts/cosmos/scripts/cosmos-publisher-script.ts +++ b/contracts/cosmos/scripts/cosmos-publisher-script.ts @@ -3,12 +3,16 @@ import { Redis } from '@dendreth/relay/implementations/redis'; import { CosmosContract } from '@dendreth/relay/implementations/cosmos-contract'; import { publishProofs } from '@dendreth/relay/on_chain_publisher'; import { checkConfig } from '@dendreth/utils/ts-utils/common-utils'; -import { getNetworkConfig } from '@dendreth/relay/utils/get_current_network_config'; +import { + NetworkConfig, + getNetworkConfig, + isSupportedFollowNetwork, +} from '@dendreth/relay/utils/get_current_network_config'; async function publishTask() { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); @@ -17,17 +21,12 @@ async function publishTask() { const followNetwork = process.argv[4]; const slotsJump = Number(process.argv[5]); - if ( - followNetwork !== 'mainnet' && - followNetwork !== 'pratter' && - followNetwork !== 'sepolia' && - followNetwork !== 'sepolia' - ) { + if (!isSupportedFollowNetwork(followNetwork)) { console.warn('This follownetwork is not specified in networkconfig'); return; } - const currentNetwork = await getNetworkConfig(followNetwork); + const currentNetwork = await getNetworkConfig(followNetwork as NetworkConfig); let address; let rpcEndpoint; diff --git a/contracts/cosmos/verifier/typescript/verifier-make-update.ts b/contracts/cosmos/verifier/typescript/verifier-make-update.ts index 779f314d8..16f156bc9 100644 --- a/contracts/cosmos/verifier/typescript/verifier-make-update.ts +++ b/contracts/cosmos/verifier/typescript/verifier-make-update.ts @@ -3,7 +3,7 @@ import { exec as exec_ } from 'node:child_process'; import { calculateFee, GasPrice } from '@cosmjs/stargate'; import { CosmosClientWithWallet } from '@dendreth/utils/cosmos-utils/cosmos-utils'; -import { getRootDir } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir } from '@dendreth/utils/ts-utils/common-utils'; const exec = promisify(exec_); @@ -14,7 +14,6 @@ export async function updateVerifierContract( updateFile: string, target: string, ) { - const rootDir = await getRootDir(); const contractDir = rootDir + `/contracts/cosmos/verifier/` + target; const pathToVerifyUtils = diff --git a/contracts/eos/scripts/eos-publisher-script.ts b/contracts/eos/scripts/eos-publisher-script.ts index 3754e2809..277cc8d14 100644 --- a/contracts/eos/scripts/eos-publisher-script.ts +++ b/contracts/eos/scripts/eos-publisher-script.ts @@ -2,13 +2,17 @@ import { getBeaconApi } from '@dendreth/relay/implementations/beacon-api'; import { Redis } from '@dendreth/relay/implementations/redis'; import { EOSContract } from '@dendreth/relay/implementations/eos-contract'; import { publishProofs } from '@dendreth/relay/on_chain_publisher'; -import { getNetworkConfig } from '@dendreth/relay/utils/get_current_network_config'; +import { + NetworkConfig, + getNetworkConfig, + isSupportedFollowNetwork, +} from '@dendreth/relay/utils/get_current_network_config'; import { checkConfig } from '@dendreth/utils/ts-utils/common-utils'; async function publishTask() { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, SLOT_JUMP: Number(process.env.SLOT_JUMP), }; @@ -17,17 +21,12 @@ async function publishTask() { const contractAddress = process.argv[3]; const followNetwork = process.argv[4]; - if ( - followNetwork !== 'mainnet' && - followNetwork !== 'pratter' && - followNetwork !== 'sepolia' && - followNetwork !== 'sepolia' - ) { + if (!isSupportedFollowNetwork(followNetwork)) { console.warn('This follownetwork is not specified in networkconfig'); return; } - const currentNetwork = await getNetworkConfig(followNetwork); + const currentNetwork = await getNetworkConfig(followNetwork as NetworkConfig); console.log('Account balance:'); diff --git a/libs/typescript/cosmos-utils/cosmos-utils.ts b/libs/typescript/cosmos-utils/cosmos-utils.ts index 6dc688d7d..6fa2d076c 100644 --- a/libs/typescript/cosmos-utils/cosmos-utils.ts +++ b/libs/typescript/cosmos-utils/cosmos-utils.ts @@ -1,10 +1,9 @@ import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'; import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; import { GasPrice } from '@cosmjs/stargate'; -import { getRootDir } from '../ts-utils/common-utils'; +import { rootDir } from '../ts-utils/common-utils'; export async function getCosmosContractArtifacts(contract: string) { - const rootDir = await getRootDir(); var contractDir; if (contract == 'light-client') { contractDir = `${rootDir}/contracts/cosmos/${contract}`; diff --git a/libs/typescript/ts-utils/common-utils.ts b/libs/typescript/ts-utils/common-utils.ts index 4f07cff07..1b7d4880e 100644 --- a/libs/typescript/ts-utils/common-utils.ts +++ b/libs/typescript/ts-utils/common-utils.ts @@ -6,6 +6,8 @@ import { assert } from 'console'; const exec = promisify(exec_); +export const rootDir = getEnvString('GIT_ROOT'); + export function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } @@ -127,13 +129,6 @@ export function appendJsonFile(filePath: string, data: any) { fs.writeFileSync(filePath, JSON.stringify(fileData, null, 2)); } -export async function getRootDir() { - return (await exec('git rev-parse --show-toplevel')).stdout.replace( - /\s/g, - '', - ); -} - export function assertNotNull( value: T | null | undefined, errorMessage?: string, @@ -174,7 +169,6 @@ export function getSecretEnvString(varName: string) { return ''; } else { let path = process.env[varName]; - const rootDir = getEnvString('GIT_ROOT'); return fs.readFileSync(rootDir + path, 'ascii').trim(); } } diff --git a/libs/typescript/ts-utils/prometheus-utils.ts b/libs/typescript/ts-utils/prometheus-utils.ts index 158414080..d597398e9 100644 --- a/libs/typescript/ts-utils/prometheus-utils.ts +++ b/libs/typescript/ts-utils/prometheus-utils.ts @@ -7,17 +7,17 @@ import express from 'express'; const register = new client.Registry(); const logger = getGenericLogger(); -let network: string; +let followNetwork: string; -export function initPrometheusSetup(port?: number, curNetwork?: string) { +export function initPrometheusSetup(port?: number, curFollowNetwork?: string) { const app = express(); if (!port) { // Only for pollUpdates port = 2999; } - if (curNetwork) { - network = curNetwork; + if (curFollowNetwork) { + followNetwork = curFollowNetwork; } app.get('/metrics', async (req, res) => { @@ -53,13 +53,18 @@ export async function prometheusTiming(func: () => T, funcName: string) { } finally { const end = process.hrtime(start); const durationSeconds = end[0] + end[1] / 1e9; - logger.info( - `Logging ${funcName} on ${network} - duration: ${durationSeconds}`, - ); - + if (followNetwork == undefined) { + logger.info( + `Executing method: ${funcName} with duration: ${durationSeconds}`, + ); + } else { + logger.info( + `Executing method: ${funcName} on follow-network: ${followNetwork} with duration: ${durationSeconds}`, + ); + } if (functionExecutionTimeSummary) { functionExecutionTimeSummary - .labels(funcName, network) + .labels(funcName, followNetwork) .observe(durationSeconds); } } diff --git a/libs/typescript/ts-utils/ssz-utils.ts b/libs/typescript/ts-utils/ssz-utils.ts index 2be42cef3..fff8f5eee 100644 --- a/libs/typescript/ts-utils/ssz-utils.ts +++ b/libs/typescript/ts-utils/ssz-utils.ts @@ -110,7 +110,7 @@ export async function getBlockHeaderFromUpdate(head) { export function computeSyncCommitteePeriodAt( slot: bigint, slots_per_period: bigint, -) { +): bigint { return slot / slots_per_period; } diff --git a/process-compose.yaml b/process-compose.yaml index 459ae1cb9..c3d7f48de 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -1,16 +1,8 @@ processes: - setup: - description: setup + downloadZkAndDatFiles: + description: download .zk and .dat files and verify their checksum working_dir: ./relay/process-compose-scripts/ - command: ./start-setup.sh - - proverserver_check: - description: check if proverserver is live - working_dir: ./relay/process-compose-scripts/ - command: ./check-proverserver.sh - depends_on: - setup: - condition: process_completed + command: ./download-zk-and-dat-files.sh redis: description: redis @@ -18,21 +10,34 @@ processes: working_dir: ./relay/process-compose-scripts/ command: ./start-redis.sh depends_on: - setup: + downloadZkAndDatFiles: condition: process_completed availability: restart: always proverserver: description: proverserver + environment: + - 'HOST = ${PROVER_SERVER_HOST}' log_location: ./logs/prover_server.log - working_dir: ./relay/process-compose-scripts/ - command: ./start-proverserver.sh + working_dir: ./ + command: proverServer ${PROVER_SERVER_PORT} data/light_client.zkey depends_on: - setup: + downloadZkAndDatFiles: condition: process_completed availability: restart: always + readiness_probe: + http_get: + host: $HOST + scheme: http + path: '/status' + port: ${PROVER_SERVER_PORT} + initial_delay_seconds: 10 + period_seconds: 10 + success_threshold: 1 + timeout_seconds: 1 + failure_threshold: 120 prometheus: description: prometheus @@ -40,7 +45,7 @@ processes: command: ./start-prometheus.sh working_dir: ./relay/process-compose-scripts/ depends_on: - setup: + downloadZkAndDatFiles: condition: process_completed availability: restart: always @@ -73,80 +78,89 @@ processes: command: yarn ts ./workers/cleaner.ts working_dir: ./relay/workers depends_on: - setup: + downloadZkAndDatFiles: condition: process_completed sepolia: - description: sepolia + description: Start generating proofs for the contract on ${LC_SEPOLIA} and update it with them log_location: ./logs/sepolia.log command: yarn hardhat start-publishing --light-client ${LC_SEPOLIA} --network sepolia --follow-network ${FOLLOW_NETWORK_SEPOLIA} --slots-jump ${SLOTS_JUMP} --hashi ${SEPOLIA_HASHI} --prometheus-port 3004 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy fantom: - description: fantom + description: Start generating proofs for the contract on ${LC_FANTOM} and update it with them log_location: ./logs/fantom.log command: yarn hardhat start-publishing --light-client ${LC_FANTOM} --network fantom --follow-network ${FOLLOW_NETWORK_FANTOM} --slots-jump ${SLOTS_JUMP} --prometheus-port 3007 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy alfajores: - description: alfajores-celo + description: Start generating proofs for the contract on ${LC_ALFAJORES} and update it with them log_location: ./logs/alfajores.log command: yarn hardhat start-publishing --light-client ${LC_ALFAJORES} --network celo --follow-network ${FOLLOW_NETWORK_CELO} --slots-jump ${SLOTS_JUMP} --prometheus-port 3008 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy bsc: - description: bsc + description: Start generating proofs for the contract on ${LC_BSC} and update it with them log_location: ./logs/bsc.log command: yarn hardhat start-publishing --light-client ${LC_BSC} --network bsc --follow-network ${FOLLOW_NETWORK_BSC} --slots-jump ${SLOTS_JUMP} --prometheus-port 3009 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy chiado: - description: chiado + description: Start generating proofs for the contract on ${LC_CHIADO} and update it with them log_location: ./logs/chiado.log command: yarn hardhat start-publishing --light-client ${LC_CHIADO} --network chiado --follow-network ${FOLLOW_NETWORK_CHIADO} --slots-jump ${SLOTS_JUMP} --hashi ${CHIADO_HASHI} --prometheus-port 3010 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy aurora: - description: aurora + description: Start generating proofs for the contract on ${LC_AURORA} and update it with them log_location: ./logs/aurora.log command: yarn hardhat start-publishing --light-client ${LC_AURORA} --network aurora --follow-network ${FOLLOW_NETWORK_AURORA} --slots-jump ${SLOTS_JUMP} --prometheus-port 3013 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy gnosis: - description: 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 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy lukso: - description: lukso + description: Start generating proofs for the contract on ${LC_LUKSO} and update it with them log_location: ./logs/lukso.log command: yarn hardhat start-publishing --light-client ${LC_LUKSO} --network lukso --follow-network ${FOLLOW_NETWORK_LUKSO} --slots-jump ${SLOTS_JUMP} --hashi ${LUKSO_HASHI} --prometheus-port 3015 working_dir: ./beacon-light-client/solidity depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy + + mainnet: + description: Start generating proofs for the contract on ${LC_MAINNET} and update it with them + log_location: ./logs/mainnet.log + command: yarn hardhat start-publishing --light-client ${LC_MAINNET} --network mainnet --follow-network ${FOLLOW_NETWORK_MAINNET} --slots-jump ${SLOTS_JUMP} --hashi ${MAINNET_HASHI} --prometheus-port 3015 + working_dir: ./beacon-light-client/solidity + depends_on: + proverserver: + condition: process_healthy general_logs: description: general_logs @@ -154,5 +168,5 @@ processes: command: yarn ts relayer_logger.ts working_dir: ./relay depends_on: - proverserver_check: - condition: process_completed + proverserver: + condition: process_healthy diff --git a/relay/implementations/publish_evm_transaction.ts b/relay/implementations/publish_evm_transaction.ts index 1db933195..974f55f5c 100644 --- a/relay/implementations/publish_evm_transaction.ts +++ b/relay/implementations/publish_evm_transaction.ts @@ -24,6 +24,7 @@ export async function publishTransaction( web3: Web3, transactionSpeed: TransactionSpeed, spread?: boolean, + chainId?: number, ) { const transactionCount = await contract.signer.getTransactionCount(); @@ -71,6 +72,32 @@ export async function publishTransaction( }); } + switch (chainId) { + case 11155111: { + console.log( + `A transaction was uploaded, to see it go to: https://sepolia.etherscan.io/tx/${transaction.hash}`, + ); + break; + } + case 10200: { + console.log( + `A transaction was uploaded, to see it go to: https://gnosis-chiado.blockscout.com/tx/${transaction.hash}`, + ); + break; + } + case 4201: { + console.log( + `A transaction was uploaded, to see it go to: https://explorer.consensus.testnet.lukso.network/tx/${transaction.hash}`, + ); + break; + } + default: { + console.log( + `A transaction was uploaded, cant send you to a explorer, because I dont have one for chainId: ${chainId}, transaction hash is: ${transaction.hash}`, + ); + } + } + logger.info(JSON.stringify(transaction)); transactionPromise = transaction.wait(); diff --git a/relay/implementations/solidity-contract.ts b/relay/implementations/solidity-contract.ts index 8a976540e..277331b5b 100644 --- a/relay/implementations/solidity-contract.ts +++ b/relay/implementations/solidity-contract.ts @@ -43,7 +43,7 @@ export class SolidityContract implements ISmartContract { await publishTransaction( this.lightClientContract, - 'light_client_update', + 'lightClientUpdate', { ...update, a, diff --git a/relay/on_chain_publisher.ts b/relay/on_chain_publisher.ts index f02166695..570b17318 100644 --- a/relay/on_chain_publisher.ts +++ b/relay/on_chain_publisher.ts @@ -31,8 +31,8 @@ export async function publishProofs( transactionSpeed: TransactionSpeed = 'avg', ) { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); @@ -153,8 +153,6 @@ export async function postUpdateOnChain( .padStart(64, '0'), }; - logger.info(JSON.stringify(update)); - if (hashiAdapterContract) { const finalizedHeaderSlot = await beaconApi.getBlockSlot( update.finalizedHeaderRoot, @@ -170,11 +168,8 @@ export async function postUpdateOnChain( await publishTransaction( hashiAdapterContract, - 'storeBlockHeader(uint32,uint64,bytes32[],uint256,bytes32[],bytes32,bytes32[],(bytes32,uint256,bytes32,bytes32,uint256[2],uint256[2][2],uint256[2]))', + 'storeBlockHeader(uint256,bytes32[],bytes32,bytes32[],(bytes32,uint256,bytes32,bytes32,uint256[2],uint256[2][2],uint256[2]))', [ - (await hashiAdapterContract.provider.getNetwork()).chainId, - finalizedHeaderSlot, - hashiInfo.slotProof.map(x => '0x' + x), hashiInfo.blockNumber, hashiInfo.blockNumberProof.map(x => '0x' + x), '0x' + hashiInfo.blockHash, @@ -184,6 +179,9 @@ export async function postUpdateOnChain( new Web3(rpcEndpoint!), transactionSpeed, true, + ( + await hashiAdapterContract.provider.getNetwork() + ).chainId, ); } else { await lightClientContract.postUpdateOnChain({ diff --git a/relay/process-compose-scripts/check-proverserver.sh b/relay/process-compose-scripts/check-proverserver.sh deleted file mode 100755 index b4af421b5..000000000 --- a/relay/process-compose-scripts/check-proverserver.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -source "${GIT_ROOT}/.env" - -if [[ -z "${PROVER_SERVER_HOST}" ]] && [[ -z "${PROVER_SERVER_PORT}" ]]; then - PROVER_SERVER_HOST="http://127.0.0.1" - PROVER_SERVER_PORT="5000" -fi - -check_proverserver() { - netstat -tuln | grep ":${PROVER_SERVER_PORT}" >/dev/null -} - -while ! check_proverserver; do - echo "ProverServer is not running on port ${PROVER_SERVER_PORT}. Waiting..." - sleep 5 -done - -echo "ProverServer is up and running on port ${PROVER_SERVER_PORT}!" diff --git a/relay/process-compose-scripts/start-setup.sh b/relay/process-compose-scripts/download-zk-and-dat-files.sh similarity index 57% rename from relay/process-compose-scripts/start-setup.sh rename to relay/process-compose-scripts/download-zk-and-dat-files.sh index 5d5b740a3..5d2e3072b 100755 --- a/relay/process-compose-scripts/start-setup.sh +++ b/relay/process-compose-scripts/download-zk-and-dat-files.sh @@ -16,31 +16,48 @@ calculate_checksum() { } download_zkey_file() { - echo "Downloading zkey file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey ..." - curl https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey >"${GIT_ROOT}/data/light_client.zkey" +if [[ -z "${LIGHT_CLIENT_ZKEY_DOWNLOAD_LOCATION}" ]]; then + echo "Light_Client_ZKEY_DOWNLOAD_LOCATION environment variables are not set. Using default values." + LIGHT_CLIENT_ZKEY_DOWNLOAD_LOCATION="https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey" + echo "This might take a while as the file is 52G" +else + echo "Using download zkey settings from environment variables" +fi - CALCULATED_ZKEY_SUM=$(calculate_checksum "${GIT_ROOT}/data/light_client.zkey") + echo "Downloading zkey file from "${LIGHT_CLIENT_ZKEY_DOWNLOAD_LOCATION}" ..." + + curl "${LIGHT_CLIENT_ZKEY_DOWNLOAD_LOCATION}" >"data/light_client.zkey" + + CALCULATED_ZKEY_SUM=$(calculate_checksum data/light_client.zkey) if [ "${ZKEY_B3SUM_SUM}" = "${CALCULATED_ZKEY_SUM}" ]; then - echo "Zkey file downloaded successfully to ${GIT_ROOT}/data/light_client.zkey" + echo "Zkey file downloaded successfully to data/light_client.zkey" else - echo "Failed to download zkey file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey" + echo "Failed to download zkey file from "${LIGHT_CLIENT_ZKEY_DOWNLOAD_LOCATION} exit 1 fi } download_dat_file() { - echo "Downloading .dat file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat ..." - curl -k https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat >"data/light_client.dat" +if [[ -z "${LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION}" ]]; then + echo "LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION environment variables are not set. Using default values." + LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION="https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat" +else + echo "Using download dat settings from environment variables" +fi - CALCULATED_DAT_SUM=$(calculate_checksum "${GIT_ROOT}/data/light_client.dat") + echo "Downloading .dat file from "${LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION}" ..." + + curl -k "${LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION}" >"data/light_client.dat" + + CALCULATED_DAT_SUM=$(calculate_checksum data/light_client.dat) if [ "${DAT_B3SUM_SUM}" = "${CALCULATED_DAT_SUM}" ]; then - echo ".dat file downloaded successfully to ${GIT_ROOT}/data/light_client.dat" + echo ".dat file downloaded successfully to data/light_client.dat" else - echo "Failed to download .dat file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat" + echo "Failed to download .dat file from "${LIGHT_CLIENT_DAT_DOWNLOAD_LOCATION}"" exit 1 fi } diff --git a/relay/process-compose-scripts/start-proverserver.sh b/relay/process-compose-scripts/start-proverserver.sh deleted file mode 100755 index 6388a789f..000000000 --- a/relay/process-compose-scripts/start-proverserver.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -source "${GIT_ROOT}/.env" - -if [[ -z "${PROVER_SERVER_HOST}" ]] && [[ -z "${PROVER_SERVER_PORT}" ]]; then - echo "PROVER_SERVER_HOST and PROVER_SERVER_PORT environment variables are not set. Using default values." - PROVER_SERVER_HOST="http://127.0.0.1" - PROVER_SERVER_PORT="5000" -else - echo "Using prover server settings from environment variables" -fi - -if [[ "${PROVER_SERVER_HOST}" == "http://127.0.0.1" ]]; then - ( - cd "${GIT_ROOT}" || exit 1 - proverServer "${PROVER_SERVER_PORT}" "${GIT_ROOT}/data/light_client.zkey" - echo "Prover server started with command" - ) - - max_attempts=300 # 300 attempts * 2s delay = 10 minutes - server_started=false - - echo "Waiting for server to start..." - - for ((i = 1; i <= max_attempts; i++)); do - response=$(curl -s -o /dev/null -w "%{http_code}" "${PROVER_SERVER_HOST}":"${PROVER_SERVER_PORT}"/status) - - if [ "${response}" -eq 200 ]; then - echo "Server is up and running." - server_started=true - break - fi - - echo "Attempt ${i}: Server is not responding. Waiting for 2 seconds..." - sleep 2 - done - - if [ ${server_started} == false ]; then - echo "Server failed to start after 5 minutes. Exiting." - exit 1 - fi -else - echo "Using remote prover server at ${PROVER_SERVER_HOST}:${PROVER_SERVER_PORT}" -fi diff --git a/relay/process-compose-scripts/start-redis.sh b/relay/process-compose-scripts/start-redis.sh index 481b6d2d1..20cf09384 100755 --- a/relay/process-compose-scripts/start-redis.sh +++ b/relay/process-compose-scripts/start-redis.sh @@ -19,7 +19,12 @@ else if [[ "${REDIS_HOST}" == "localhost" ]] && [[ "${REDIS_PORT}" == "6379" ]]; then echo "Starting local Redis server..." + mkdir "${GIT_ROOT}/redis-server" + ( + cd "${GIT_ROOT}/redis-server" || exit 1 redis-server --appendonly yes + + ) echo "Local Redis server started" else echo "Using remote Redis server at ${REDIS_HOST}:${REDIS_PORT}" diff --git a/relay/relayer_logger.ts b/relay/relayer_logger.ts index 4efaada3e..a95ffd9e7 100644 --- a/relay/relayer_logger.ts +++ b/relay/relayer_logger.ts @@ -9,8 +9,8 @@ import { getGenericLogger } from '@dendreth/utils/ts-utils/logger'; const logger = getGenericLogger(); const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); diff --git a/relay/run-relay.sh b/relay/run-relay.sh deleted file mode 100755 index e56ab5ebe..000000000 --- a/relay/run-relay.sh +++ /dev/null @@ -1,285 +0,0 @@ -#!/usr/bin/env bash - -ZKEY_B3SUM_SUM='7bd1baf6e4aa1bb97933df06f68b26f8aa034e6743ff52c4dd7f6097d6e7d104' -DAT_B3SUM_SUM='c94eb86af7c0451a4277a7bdfc90232a9db75c192d6852ad18baa9a46e1e52e5' -source .env -(cd beacon-light-client/solidity/ && yarn hardhat compile) - -process-compose -t=false & - -calculate_checksum() { - local FILE_PATH=$1 - b3sum "${FILE_PATH}" | cut -d ' ' -f 1 -} - -download_zkey_file() { - echo "Downloading zkey file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey ..." - - curl https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey >"data/light_client.zkey" - - CALCULATED_ZKEY_SUM=$(calculate_checksum data/light_client.zkey) - - if [ "${ZKEY_B3SUM_SUM}" = "${CALCULATED_ZKEY_SUM}" ]; then - echo "Zkey file downloaded successfully to data/light_client.zkey" - else - echo "Failed to download zkey file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.zkey" - exit 1 - fi -} - -download_dat_file() { - echo "Downloading .dat file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat ..." - - curl -k https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat >"data/light_client.dat" - - CALCULATED_DAT_SUM=$(calculate_checksum data/light_client.dat) - - if [ "${DAT_B3SUM_SUM}" = "${CALCULATED_DAT_SUM}" ]; then - echo ".dat file downloaded successfully to data/light_client.dat" - else - echo "Failed to download .dat file from https://dendrethstorage.blob.core.windows.net/light-client/light-client.dat" - exit 1 - fi -} - -mkdir -p "${GIT_ROOT}/data" - -if [ ! -f "data/light_client.zkey" ]; then - download_zkey_file -else - CALCULATED_ZKEY_SUM=$(calculate_checksum data/light_client.zkey) - echo "${CALCULATED_ZKEY_SUM}" - if [ "${ZKEY_B3SUM_SUM}" = "${CALCULATED_ZKEY_SUM}" ]; then - echo "Using cached zkey file at data/light_client.zkey" - else - echo "Wrong version of light_client.zkey cached downloading again..." - download_zkey_file - fi -fi - -if [ ! -f "data/light_client.dat" ]; then - download_dat_file -else - CALCULATED_DAT_SUM=$(calculate_checksum data/light_client.dat) - echo "${CALCULATED_DAT_SUM}" - if [ "${DAT_B3SUM_SUM}" = "${CALCULATED_DAT_SUM}" ]; then - echo "Using cached .dat file at data/light_client.dat" - else - echo "Wrong version of light_client.dat cached downloading again..." - download_dat_file - fi -fi - -# rapidnskark prover server searches for the witness generator exe in build directory -mkdir -p build -cp relay/light_client build/light_client -cp data/light_client.dat light_client.dat - -if [[ -z "${REDIS_HOST}" ]] && [[ -z "${REDIS_PORT}" ]]; then - echo "REDIS_HOST and REDIS_PORT environment variables are not set. Using default values." - REDIS_HOST="localhost" - REDIS_PORT="6379" -else - echo "Using Redis settings from environment variables" -fi - -if [[ -z "${PROVER_SERVER_HOST}" ]] && [[ -z "${PROVER_SERVER_PORT}" ]]; then - echo "PROVER_SERVER_HOST and PROVER_SERVER_PORT environment variables are not set. Using default values." - PROVER_SERVER_HOST="http://127.0.0.1" - PROVER_SERVER_PORT="5000" -else - echo "Using prover server settings from environment variables" -fi - -if [[ "${PROVER_SERVER_HOST}" == "http://127.0.0.1" ]]; then - echo "Starting local prover server..." - process-compose process start proverserver - echo "Prover server started with command" - - max_attempts=300 # 300 attempts * 2s delay = 10 minutes - server_started=false - - echo "Waiting for server to start..." - - for ((i = 1; i <= max_attempts; i++)); do - response=$(curl -s -o /dev/null -w "%{http_code}" "${PROVER_SERVER_HOST}":"${PROVER_SERVER_PORT}"/status) - - if [ "${response}" -eq 200 ]; then - echo "Server is up and running." - server_started=true - break - fi - - echo "Attempt ${i}: Server is not responding. Waiting for 2 seconds..." - sleep 2 - done - - if [ ${server_started} == false ]; then - echo "Server failed to start after 5 minutes. Exiting." - exit 1 - fi -else - echo "Using remote prover server at ${PROVER_SERVER_HOST}:${PROVER_SERVER_PORT}" -fi - -if [[ "${REDIS_HOST}" == "localhost" ]] && [[ "${REDIS_PORT}" == "6379" ]]; then - echo "Starting local Redis server..." - process-compose process start redis - echo "Local Redis server started" -else - echo "Using remote Redis server at ${REDIS_HOST}:${REDIS_PORT}" -fi - -echo "Starting Prometheus server on 9090" -process-compose process start prometheus -echo "Prometheus server started" - -# Run the polling update task -echo "Starting the polling update task" -process-compose process start pollUpdatesWorker -echo "Polling update task started" - -# Run the proof generation task -echo "Starting the proof generation task" -process-compose process start proofGenerationWorker -echo "Proof generation task started" - -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 - -run_network_tasks() { - - # Run hardhat tasks for different networks - if [ -n "${LC_GOERLI}" ]; then - echo "Starting light client for Goerli network" - process-compose process start goerli - else - echo "Skipping Goerli network" - fi - - if [ -n "${LC_OPTIMISTIC_GOERLI}" ]; then - echo "Starting light client for Optimistic Goerli network" - process-compose process start goeoptimisticGoerlirli - else - echo "Skipping Optimistic Goerli network" - fi - - if [ -n "${LC_BASE_GOERLI}" ]; then - echo "Starting light client for Base Goerli network" - process-compose process start baseGoerli - else - echo "Skipping Base Goerli network" - fi - - if [ -n "${LC_ARBITRUM_GOERLI}" ]; then - echo "Starting light client for Arbitrum Goerli network" - process-compose process start arbitrumGoerli - else - echo "Skipping Arbitrum Goerli network" - fi - - if [ -n "${LC_SEPOLIA}" ]; then - echo "Starting light client for Sepolia network" - process-compose process start sepolia - else - echo "Skipping Sepolia network" - fi - - if [ -n "${LC_MUMBAI}" ]; then - echo "Starting light client for Mumbai network" - process-compose process start mumbai - else - echo "Skipping Mumbai network" - fi - - if [ -n "${LC_FUJI}" ]; then - echo "Starting light client for Fuji network" - process-compose process start fuji - else - echo "Skipping Fuji network" - fi - - if [ -n "${LC_FANTOM}" ]; then - echo "Starting light client for Fantom network" - process-compose process start fantom - else - echo "Skipping Fantom network" - fi - - if [ -n "${LC_ALFAJORES}" ]; then - echo "Starting light client for Alfajores network" - process-compose process start alfajores - else - echo "Skipping Alfajores network" - fi - - if [ -n "${LC_BSC}" ]; then - echo "Starting light client for BSC network" - process-compose process start bsc - else - echo "Skipping BSC network" - fi - - if [ -n "${LC_AURORA}" ]; then - echo "Starting light client for Aurora network" - process-compose process start aurora - else - echo "Skipping Aurora network" - fi - - if [ -n "${LC_GNOSIS}" ]; then - echo "Starting light client for Gnosis network" - process-compose process start gnosis - else - echo "Skipping Gnosis network" - fi - - if [ -n "${LC_CHIADO}" ]; then - echo "Starting light client for Chiado network" - process-compose process start chiado - else - echo "Skipping Chiado network" - fi - - if [ -n "${LC_EVMOS}" ]; then - echo "Starting light client for EVMOS network" - process-compose process start evmos - else - echo "Skipping EVMOS network" - fi - - if [ -n "${LC_MALAGA}" ]; then - echo "Starting light client for Malaga network" - process-compose process start malaga - else - echo "Skipping Malaga network" - fi - - echo "Everything started for ${FOLLOW_NETWORK}" -} - -# Call the function based on PRATTER or MAINNET -if [[ "${PRATTER}" == "TRUE" ]]; then - export FOLLOW_NETWORK="pratter" - run_network_tasks -fi - -if [[ "${MAINNET}" == "TRUE" ]]; then - export FOLLOW_NETWORK="mainnet" - run_network_tasks -fi - -process-compose process start cleaner - -process-compose process start general_logs - -echo "____________Starting Logs____________" - -tail -f .logs/prover_server.log logs/general_logs.log logs/pollUpdatesWorker.log logs/proofGenerationWorker.log logs/goerli.log logs/optimisticGoerli.log logs/baseGoerli.log logs/arbitrumGoerli.log logs/sepolia.log logs/mumbai.log logs/gnosis.log diff --git a/relay/utils/discord_monitor.ts b/relay/utils/discord_monitor.ts index ddc3a94a7..7a0c0a9b2 100644 --- a/relay/utils/discord_monitor.ts +++ b/relay/utils/discord_monitor.ts @@ -1,212 +1,160 @@ -import { SolidityContract } from '@/implementations/solidity-contract'; -import { getBeaconApi, BeaconApi } from '@/implementations/beacon-api'; import { ethers } from 'ethers'; -import { sleep } from '@dendreth/utils/ts-utils/common-utils'; -import { GatewayIntentBits, Events, Partials } from 'discord.js'; import * as Discord from 'discord.js'; -import lc_abi_json from '@dendreth/solidity/artifacts/BeaconLightClient.json'; - -const env = process.env; +import contractAbi from '../../beacon-light-client/solidity/tasks/hashi_abi.json'; +import { getEnvString } from '@dendreth/utils/ts-utils/common-utils'; + +async function getLastEventTime( + contract: ethers.Contract, + network: string, +): Promise { + const latestBlock = await contract.provider.getBlockNumber(); + const filter = contract.filters.HashStored(); + + const events = await contract.queryFilter( + filter, + latestBlock - 10000, + latestBlock, + ); + if (events.length === 0) { + console.log(`No events found for network '${network}'.`); + throw new Error('No events found.'); + } -interface ContractData { - RPC: string; - Address: string; - SolidityContract?: SolidityContract; + return (await events[events.length - 1].getBlock()).timestamp * 1000; } -type SolidityDictionary = { - [name: string]: ContractData; -}; - -class DiscordMonitor { - private readonly contracts: SolidityDictionary = {}; - - constructor( - private readonly client: Discord.Client, - private readonly beaconApi: BeaconApi, - private readonly alert_threshold: number, - ) { - if (env.GOERLI_RPC && env.LC_GOERLI) { - this.contracts['Goerli'] = { - RPC: env.GOERLI_RPC, - Address: env.LC_GOERLI, - }; - } - if (env.OPTIMISTIC_GOERLI_RPC && env.LC_OPTIMISTIC_GOERLI) { - this.contracts['OptimisticGoerli'] = { - RPC: env.OPTIMISTIC_GOERLI_RPC, - Address: env.LC_OPTIMISTIC_GOERLI, - }; - } - if (env.BASE_GOERLI_RPC && env.LC_BASE_GOERLI) { - this.contracts['BaseGoerli'] = { - RPC: env.BASE_GOERLI_RPC, - Address: env.LC_BASE_GOERLI, - }; - } +// Monitor function that checks for contract updates and dispatches Discord alerts +async function checkContractUpdate( + providerUrl: string, + contractAddress: string, + network: string, + alertThresholdMinutes: number, + discordClient: Discord.Client, +) { + try { + const provider = new ethers.providers.JsonRpcProvider(providerUrl); + const contract = new ethers.Contract( + contractAddress, + contractAbi, + provider, + ); - if (env.ARBITRUM_GOERLI_RPC && env.LC_ARBITRUM_GOERLI) { - this.contracts['ArbitrumGoerli'] = { - RPC: env.ARBITRUM_GOERLI_RPC, - Address: env.LC_ARBITRUM_GOERLI, - }; - } - if (env.SEPOLIA_RPC && env.LC_SEPOLIA) { - this.contracts['Sepolia'] = { - RPC: env.SEPOLIA_RPC, - Address: env.LC_SEPOLIA, - }; - } - if (env.MUMBAI_RPC && env.LC_MUMBAI) { - this.contracts['Mumbai'] = { - RPC: env.MUMBAI_RPC, - Address: env.LC_MUMBAI, - }; - } - if (env.FANTOM_RPC && env.LC_FANTOM) { - this.contracts['Fantom'] = { - RPC: env.FANTOM_RPC, - Address: env.LC_FANTOM, - }; - } - if (env.CHIADO_RPC && env.LC_CHIADO) { - this.contracts['Chiado'] = { - RPC: env.CHIADO_RPC, - Address: env.LC_CHIADO, - }; - } - if (env.GNOSIS_RPC && env.LC_GNOSIS) { - this.contracts['Gnosis'] = { - RPC: env.GNOSIS_RPC, - Address: env.LC_GNOSIS, - }; - } - if (env.BSC_RPC && env.LC_BSC) { - this.contracts['BSC'] = { RPC: env.BSC_RPC, Address: env.LC_BSC }; + const lastEventTime = await getLastEventTime(contract, network); + const delayInMinutes = (Date.now() - lastEventTime) / 1000 / 60; + + if (!discordClient.isReady()) { + console.error('Discord client is not ready.'); + return; } - if (env.AURORA_RPC && env.LC_AURORA) { - this.contracts['Aurora'] = { - RPC: env.AURORA_RPC, - Address: env.LC_AURORA, - }; + + const channel = discordClient.channels.cache.get( + getEnvString('CHANNEL_ID'), + ) as Discord.TextChannel; + if (!channel) { + console.error('Discord channel not found.'); + return; } - // Instantiate SolidityContracts from .env - for (let endpoint in this.contracts) { - let curLightClient = new ethers.Contract( - this.contracts[endpoint].Address, - lc_abi_json.abi, - new ethers.providers.JsonRpcProvider(this.contracts[endpoint].RPC), // Provider + if (delayInMinutes >= alertThresholdMinutes) { + const message = `@DendrETH Support Relay ⚠️ Alert: Contract on **${network}** hasn't been updated in ${delayInMinutes.toFixed( + 2, + )} minutes.`; + await channel.send(message); + } else { + console.log( + `Contract on ${network} is up to date. Last update was before: ${delayInMinutes.toFixed( + 2, + )} minutes`, ); - - let curSolidityContract = new SolidityContract( - curLightClient, - this.contracts[endpoint].RPC, + } + } catch (error) { + if (error instanceof Error) { + console.error( + `Error checking contract on network '${network}':`, + error.message, ); - this.contracts[endpoint].SolidityContract = curSolidityContract; + } else { + console.error(`Unknown error occurred on network '${network}':`, error); } } +} - public static async initializeDiscordMonitor( - alert_threshold: number, - ): Promise { - const beaconApi = await getBeaconApi([ - 'http://unstable.prater.beacon-api.nimbus.team/', - ]); - - const client = new Discord.Client({ - intents: [ - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildMessages, - GatewayIntentBits.GuildMembers, - GatewayIntentBits.DirectMessages, - ], - partials: [Partials.Channel, Partials.Message, Partials.Reaction], - }); - - const result = await client.login(env.token); - - await client.on(Events.ClientReady, async interaction => { - console.log('Client Ready!'); - console.log(`Logged in as ${client.user?.tag}!`); - }); - - return new DiscordMonitor(client, beaconApi, alert_threshold); - } +async function monitorContracts(networksAndAddresses: string[]) { + const discordClient = new Discord.Client({ + intents: [ + Discord.GatewayIntentBits.Guilds, + Discord.GatewayIntentBits.GuildMessages, + ], + }); - private async getSlotDelay(contract: SolidityContract) { - return ( - (await this.beaconApi.getCurrentHeadSlot()) - - (await contract.optimisticHeaderSlot()) - ); - } + discordClient.once(Discord.Events.ClientReady, () => { + console.log(`Logged in as ${discordClient.user?.tag}!`); + }); - private async respondToMessage() { - //TODO: Implement responsive commands - this.client.on(Events.MessageCreate, message => { - if (message.author.bot) return; + await discordClient.login(getEnvString('DISCORD_TOKEN')); - // Nice to have, responsive bot - console.log( - `Message from ${message.author.username}: ${message.content}`, - ); - if (message.content === '') console.log('Empty message'); //TODO: Bot can't read user messages - }); - } + const alertThresholdMinutes = parseInt( + getEnvString('ALERT_THRESHOLD_MINUTES'), + 10, + ); - public async dispatchMessage(messageToSend) { - let channel = this.client.channels.cache.get( - env.channel_id!, - ) as Discord.TextChannel; - if (!channel) { - channel = (await this.client.channels.fetch( - env.channel_id!, - )) as Discord.TextChannel; - } + const networks: string[] = []; - await channel.send(messageToSend); - } + for (let i = 0; i < networksAndAddresses.length; i += 2) { + const network = networksAndAddresses[i]; + const contractAddress = networksAndAddresses[i + 1]; + + try { + const rpcUrl = getEnvString(`${network.toUpperCase()}_RPC`); + + networks.push(network); - public async monitor_delay() { - for (let contract of Object.keys(this.contracts)) { - let name = contract; - let delay = await this.getSlotDelay( - this.contracts[contract].SolidityContract!, + // Immediately check the contract update, then set interval + checkContractUpdate( + rpcUrl, + contractAddress, + network, + alertThresholdMinutes, + discordClient, ); - // Dispatch - const minutes_delay = (delay * 1) / 5; - if (minutes_delay >= this.alert_threshold || delay < 0) { - let message = `Contract: ${name} is behind Beacon Head with ${minutes_delay} minutes`; - this.dispatchMessage(message); + setInterval( + () => + checkContractUpdate( + rpcUrl, + contractAddress, + network, + alertThresholdMinutes, + discordClient, + ), + 5 * 60 * 1000, + ); + } catch (error) { + if (error instanceof Error) { + console.warn(`Skipping network '${network}' due to:`, error.message); + } else { + console.warn( + `Skipping network '${network}' due to unknown error:`, + error, + ); } } } -} -(async () => { - let monitor = await DiscordMonitor.initializeDiscordMonitor( - Number(env.ping_threshold), + console.log( + `Monitoring the following networks: [ '${networks.join("', '")}' ]`, ); +} - monitor.dispatchMessage('Relayer bot starting!'); - - let retry_counter = 0; - while (true) { - if (retry_counter >= 10) { - throw new Error( - `Failed connection to Discord after ${retry_counter} retries`, - ); - } +(async () => { + const args = process.argv.slice(2); - const msTimeout = 10_000; - let waitPromise = new Promise<'timeout'>(resolve => - setTimeout(() => resolve('timeout'), msTimeout), + if (args.length === 0 || args.length % 2 !== 0) { + console.error( + 'Please specify the network and contract address pairs (e.g., sepolia 0x1234 chiado 0x5678).', ); - let response = await Promise.race([monitor.monitor_delay(), waitPromise]); - - retry_counter += response == 'timeout' ? 1 : 0; - - await sleep(env.ping_timeout); + process.exit(1); } + + await monitorContracts(args); })(); diff --git a/relay/utils/get_current_network_config.ts b/relay/utils/get_current_network_config.ts index 327516ac8..6b7cef03a 100644 --- a/relay/utils/get_current_network_config.ts +++ b/relay/utils/get_current_network_config.ts @@ -20,8 +20,23 @@ const defaultConfig: Config = { GENESIS_VALIDATORS_ROOT: '', }; +export type NetworkConfig = + | 'pratter' + | 'mainnet' + | 'sepolia' + | 'chiado' + | 'gnosis'; + +export function isSupportedFollowNetwork( + network: string, +): network is NetworkConfig { + return ['pratter', 'mainnet', 'sepolia', 'chiado', 'gnosis'].includes( + network, + ); +} + export async function getNetworkConfig( - network: 'pratter' | 'mainnet' | 'sepolia' | 'chiado', + network: NetworkConfig, ): Promise { let config: Config = { ...defaultConfig, NETWORK_NAME: network }; config.NETWORK_NAME = network; @@ -46,6 +61,11 @@ export async function getNetworkConfig( 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; diff --git a/relay/workers/cleaner.ts b/relay/workers/cleaner.ts index 8bcfe4a5c..652cb619d 100644 --- a/relay/workers/cleaner.ts +++ b/relay/workers/cleaner.ts @@ -8,8 +8,8 @@ const logger = getGenericLogger(); (async () => { const config = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(config); diff --git a/relay/workers/poll-updates/poll-updates-worker.ts b/relay/workers/poll-updates/poll-updates-worker.ts index 51932c37a..2bd386cf8 100644 --- a/relay/workers/poll-updates/poll-updates-worker.ts +++ b/relay/workers/poll-updates/poll-updates-worker.ts @@ -16,8 +16,8 @@ initPrometheusSetup(); (async () => { const updatePollingConfig = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(updatePollingConfig); diff --git a/relay/workers/prover/prover-worker.ts b/relay/workers/prover/prover-worker.ts index 01f5c96b2..410182f05 100644 --- a/relay/workers/prover/prover-worker.ts +++ b/relay/workers/prover/prover-worker.ts @@ -10,8 +10,8 @@ import yargs from 'yargs'; (async () => { const proverConfig = { - REDIS_HOST: process.env.REDIS_HOST, - REDIS_PORT: Number(process.env.REDIS_PORT), + REDIS_HOST: process.env.REDIS_HOST || 'localhost', + REDIS_PORT: Number(process.env.REDIS_PORT) || 6379, }; checkConfig(proverConfig); diff --git a/shell.nix b/shell.nix index 52c196ef1..c23a4920e 100644 --- a/shell.nix +++ b/shell.nix @@ -41,7 +41,7 @@ # scripts/check-user-env-file-contents.sh # Set up the environment for the Solidity compiler - ./scripts/config_solidity_import_mapping.sh + # ./scripts/config_solidity_import_mapping.sh figlet "DendrETH" ''; diff --git a/tests/cosmosLightClient/test-nim-light-client-in-cosmos.ts b/tests/cosmosLightClient/test-nim-light-client-in-cosmos.ts index eaa486018..ada88764b 100644 --- a/tests/cosmosLightClient/test-nim-light-client-in-cosmos.ts +++ b/tests/cosmosLightClient/test-nim-light-client-in-cosmos.ts @@ -15,7 +15,7 @@ import { compileNimFileToWasm } from '@dendreth/utils/ts-utils/compile-nim-to-wa import { byteArrayToNumber, appendJsonFile, - getRootDir, + rootDir, } from '@dendreth/utils/ts-utils/common-utils'; import { setUpCosmosTestnet, @@ -25,8 +25,6 @@ import { gasUsed } from '../helpers/helpers'; const exec = promisify(exec_); -let rootDir; - describe('Light Client In Cosmos', () => { let gasArrayLightClient: gasUsed[] = []; let client: SigningCosmWasmClient; @@ -42,8 +40,6 @@ describe('Light Client In Cosmos', () => { const gasUsageFile = 'tests/cosmosLightClient/gasLightClient.json'; beforeAll(async () => { - rootDir = await getRootDir(); - let contractDirLightClient = rootDir + `/contracts/cosmos/light-client`; let nimFilePathLightClient = contractDirLightClient + `/lib/nim/light_client_cosmos_wrapper.nim`; diff --git a/tests/cosmosLightClient/test-verifier-in-cosmos-relay.ts b/tests/cosmosLightClient/test-verifier-in-cosmos-relay.ts index 62cbe2330..22f2551ff 100644 --- a/tests/cosmosLightClient/test-verifier-in-cosmos-relay.ts +++ b/tests/cosmosLightClient/test-verifier-in-cosmos-relay.ts @@ -12,7 +12,7 @@ import { } from '@dendreth/utils/cosmos-utils/testnet-setup'; import { CosmosContract } from '@dendreth/relay/implementations/cosmos-contract'; import { bytesToHex } from '@dendreth/utils/ts-utils/bls'; -import { getRootDir } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir } from '@dendreth/utils/ts-utils/common-utils'; import { compileContractMain } from '../../contracts/cosmos/verifier/typescript/verifier-compile-contract-and-tools'; import { @@ -40,8 +40,6 @@ describe('Light Client Verifier In Cosmos', () => { 'economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone'; beforeAll(async () => { - const rootDir = await getRootDir(); - contractDirVerifier = rootDir + `/contracts/cosmos/verifier/verifier-bncurve`; parseDataTool = `${contractDirVerifier}/nimcache/verifier_parse_data`; diff --git a/tests/eosLightClient/test-verifier-in-EOS-relay.ts b/tests/eosLightClient/test-verifier-in-EOS-relay.ts index 11949adda..28c1663c5 100644 --- a/tests/eosLightClient/test-verifier-in-EOS-relay.ts +++ b/tests/eosLightClient/test-verifier-in-EOS-relay.ts @@ -8,7 +8,7 @@ import { compileVerifierParseDataTool, replaceInTextProof, } from '../helpers/helpers'; -import { getRootDir, sleep } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir, sleep } from '@dendreth/utils/ts-utils/common-utils'; import { EOSContract } from '@dendreth/relay/implementations/eos-contract'; import { bytesToHex } from '@dendreth/utils/ts-utils/bls'; @@ -34,7 +34,6 @@ describe('Verifier in EOS', () => { const defaultDomain = '0x07000000628941ef21d1fe8c7134720add10bb91e3b02c007e0046d2472c6695'; beforeAll(async () => { - const rootDir = await getRootDir(); parseDataTool = await compileVerifierParseDataTool( 'eos', 'verifier', diff --git a/tests/eosLightClient/test-verifier-in-EOS.ts b/tests/eosLightClient/test-verifier-in-EOS.ts index 92feb8b78..812b90e15 100644 --- a/tests/eosLightClient/test-verifier-in-EOS.ts +++ b/tests/eosLightClient/test-verifier-in-EOS.ts @@ -8,7 +8,7 @@ import { compileVerifierParseDataTool, replaceInTextProof, } from '../helpers/helpers'; -import { getRootDir, sleep } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir, sleep } from '@dendreth/utils/ts-utils/common-utils'; import { getDataFromPrintHeaderResult } from '@dendreth/utils/cosmos-utils/cosmos-utils'; const exec = promisify(exec_); @@ -27,7 +27,6 @@ describe('Verifier in EOS', () => { const defaultDomain = '0x07000000628941ef21d1fe8c7134720add10bb91e3b02c007e0046d2472c6695'; beforeAll(async () => { - const rootDir = await getRootDir(); parseDataTool = await compileVerifierParseDataTool( 'eos', 'verifier', diff --git a/tests/helpers/helpers.ts b/tests/helpers/helpers.ts index f8480ce28..4819cab39 100644 --- a/tests/helpers/helpers.ts +++ b/tests/helpers/helpers.ts @@ -1,6 +1,6 @@ import { promisify } from 'node:util'; import { exec as exec_ } from 'node:child_process'; -import { getRootDir } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir } from '@dendreth/utils/ts-utils/common-utils'; const exec = promisify(exec_); @@ -26,7 +26,6 @@ async function getDirs( protocol: 'cosmos' | 'eos', contract: 'verifier' | 'light-client', ) { - const rootDir = await getRootDir(); const contractDir = `${rootDir}/contracts/${protocol}/${contract}`; return { rootDir, contractDir }; } diff --git a/tests/verify_proof/verify_given_proof_test.ts b/tests/verify_proof/verify_given_proof_test.ts index 850d17450..86eaf7cb3 100644 --- a/tests/verify_proof/verify_given_proof_test.ts +++ b/tests/verify_proof/verify_given_proof_test.ts @@ -1,7 +1,7 @@ import { beforeAll, describe, expect, test } from '@jest/globals'; import { VerifyFromPaths } from '@dendreth/utils/verify-utils/verify-given-proof-ffjavascript'; -import { getRootDir } from '@dendreth/utils/ts-utils/common-utils'; +import { rootDir } from '@dendreth/utils/ts-utils/common-utils'; describe('Check verifier build on ffjavascript', () => { let keyPath: string; @@ -10,8 +10,6 @@ describe('Check verifier build on ffjavascript', () => { let updatePath: string; beforeAll(async () => { - const rootDir = await getRootDir(); - keyPath = rootDir + '/vendor/eth2-light-client-updates/prater/capella-updates-94/vk.json'; diff --git a/vendor/snarkjs b/vendor/snarkjs index e44656d9e..0ddd56f9b 160000 --- a/vendor/snarkjs +++ b/vendor/snarkjs @@ -1 +1 @@ -Subproject commit e44656d9e7b451250038211e44c1a7d80dd76b89 +Subproject commit 0ddd56f9be79ca561e72b85ced3223cb66a2bbb4