Skip to content

Commit

Permalink
Add LightClientArbitrum (#2423)
Browse files Browse the repository at this point in the history
* Add LightClientArbitrum

* fix typos

* contract-bindings

* format and add test
  • Loading branch information
Sneh1999 authored Jan 7, 2025
1 parent 91c95b6 commit 29b2c00
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 7 deletions.
2 changes: 1 addition & 1 deletion contract-bindings/artifacts/LightClientMock_bytecode.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contract-bindings/artifacts/LightClient_bytecode.json

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions contract-bindings/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ pub mod light_client {
state_mutability: ::ethers::core::abi::ethabi::StateMutability::View,
},],
),
(
::std::borrow::ToOwned::to_owned("currentBlockNumber"),
::std::vec![::ethers::core::abi::ethabi::Function {
name: ::std::borrow::ToOwned::to_owned("currentBlockNumber"),
inputs: ::std::vec![],
outputs: ::std::vec![::ethers::core::abi::ethabi::Param {
name: ::std::string::String::new(),
kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,),
internal_type: ::core::option::Option::Some(
::std::borrow::ToOwned::to_owned("uint256"),
),
},],
constant: ::core::option::Option::None,
state_mutability: ::ethers::core::abi::ethabi::StateMutability::View,
},],
),
(
::std::borrow::ToOwned::to_owned("disablePermissionedProverMode"),
::std::vec![::ethers::core::abi::ethabi::Function {
Expand Down Expand Up @@ -959,6 +975,14 @@ pub mod light_client {
.method_hash([173, 60, 177, 204], ())
.expect("method not found (this should never happen)")
}
///Calls the contract's `currentBlockNumber` (0x378ec23b) function
pub fn current_block_number(
&self,
) -> ::ethers::contract::builders::ContractCall<M, ::ethers::core::types::U256> {
self.0
.method_hash([55, 142, 194, 59], ())
.expect("method not found (this should never happen)")
}
///Calls the contract's `disablePermissionedProverMode` (0x69cc6a04) function
pub fn disable_permissioned_prover_mode(
&self,
Expand Down Expand Up @@ -2214,6 +2238,21 @@ pub mod light_client {
abi = "UPGRADE_INTERFACE_VERSION()"
)]
pub struct UpgradeInterfaceVersionCall;
///Container type for all input parameters for the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b`
#[derive(
Clone,
::ethers::contract::EthCall,
::ethers::contract::EthDisplay,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
#[ethcall(name = "currentBlockNumber", abi = "currentBlockNumber()")]
pub struct CurrentBlockNumberCall;
///Container type for all input parameters for the `disablePermissionedProverMode` function with signature `disablePermissionedProverMode()` and selector `0x69cc6a04`
#[derive(
Clone,
Expand Down Expand Up @@ -2589,6 +2628,7 @@ pub mod light_client {
#[derive(Clone, ::ethers::contract::EthAbiType, serde::Serialize, serde::Deserialize)]
pub enum LightClientCalls {
UpgradeInterfaceVersion(UpgradeInterfaceVersionCall),
CurrentBlockNumber(CurrentBlockNumberCall),
DisablePermissionedProverMode(DisablePermissionedProverModeCall),
FinalizedState(FinalizedStateCall),
GenesisStakeTableState(GenesisStakeTableStateCall),
Expand Down Expand Up @@ -2622,6 +2662,11 @@ pub mod light_client {
{
return Ok(Self::UpgradeInterfaceVersion(decoded));
}
if let Ok(decoded) =
<CurrentBlockNumberCall as ::ethers::core::abi::AbiDecode>::decode(data)
{
return Ok(Self::CurrentBlockNumber(decoded));
}
if let Ok(decoded) =
<DisablePermissionedProverModeCall as ::ethers::core::abi::AbiDecode>::decode(data)
{
Expand Down Expand Up @@ -2733,6 +2778,9 @@ pub mod light_client {
Self::UpgradeInterfaceVersion(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Self::CurrentBlockNumber(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Self::DisablePermissionedProverMode(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Expand Down Expand Up @@ -2786,6 +2834,7 @@ pub mod light_client {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Self::UpgradeInterfaceVersion(element) => ::core::fmt::Display::fmt(element, f),
Self::CurrentBlockNumber(element) => ::core::fmt::Display::fmt(element, f),
Self::DisablePermissionedProverMode(element) => {
::core::fmt::Display::fmt(element, f)
}
Expand Down Expand Up @@ -2820,6 +2869,11 @@ pub mod light_client {
Self::UpgradeInterfaceVersion(value)
}
}
impl ::core::convert::From<CurrentBlockNumberCall> for LightClientCalls {
fn from(value: CurrentBlockNumberCall) -> Self {
Self::CurrentBlockNumber(value)
}
}
impl ::core::convert::From<DisablePermissionedProverModeCall> for LightClientCalls {
fn from(value: DisablePermissionedProverModeCall) -> Self {
Self::DisablePermissionedProverMode(value)
Expand Down Expand Up @@ -2944,6 +2998,20 @@ pub mod light_client {
Hash,
)]
pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String);
///Container type for all return fields from the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b`
#[derive(
Clone,
::ethers::contract::EthAbiType,
::ethers::contract::EthAbiCodec,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
pub struct CurrentBlockNumberReturn(pub ::ethers::core::types::U256);
///Container type for all return fields from the `finalizedState` function with signature `finalizedState()` and selector `0x9fdb54a7`
#[derive(
Clone,
Expand Down
68 changes: 68 additions & 0 deletions contract-bindings/src/light_client_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ pub mod light_client_mock {
state_mutability: ::ethers::core::abi::ethabi::StateMutability::View,
},],
),
(
::std::borrow::ToOwned::to_owned("currentBlockNumber"),
::std::vec![::ethers::core::abi::ethabi::Function {
name: ::std::borrow::ToOwned::to_owned("currentBlockNumber"),
inputs: ::std::vec![],
outputs: ::std::vec![::ethers::core::abi::ethabi::Param {
name: ::std::string::String::new(),
kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,),
internal_type: ::core::option::Option::Some(
::std::borrow::ToOwned::to_owned("uint256"),
),
},],
constant: ::core::option::Option::None,
state_mutability: ::ethers::core::abi::ethabi::StateMutability::View,
},],
),
(
::std::borrow::ToOwned::to_owned("disablePermissionedProverMode"),
::std::vec![::ethers::core::abi::ethabi::Function {
Expand Down Expand Up @@ -1065,6 +1081,14 @@ pub mod light_client_mock {
.method_hash([173, 60, 177, 204], ())
.expect("method not found (this should never happen)")
}
///Calls the contract's `currentBlockNumber` (0x378ec23b) function
pub fn current_block_number(
&self,
) -> ::ethers::contract::builders::ContractCall<M, ::ethers::core::types::U256> {
self.0
.method_hash([55, 142, 194, 59], ())
.expect("method not found (this should never happen)")
}
///Calls the contract's `disablePermissionedProverMode` (0x69cc6a04) function
pub fn disable_permissioned_prover_mode(
&self,
Expand Down Expand Up @@ -2357,6 +2381,21 @@ pub mod light_client_mock {
abi = "UPGRADE_INTERFACE_VERSION()"
)]
pub struct UpgradeInterfaceVersionCall;
///Container type for all input parameters for the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b`
#[derive(
Clone,
::ethers::contract::EthCall,
::ethers::contract::EthDisplay,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
#[ethcall(name = "currentBlockNumber", abi = "currentBlockNumber()")]
pub struct CurrentBlockNumberCall;
///Container type for all input parameters for the `disablePermissionedProverMode` function with signature `disablePermissionedProverMode()` and selector `0x69cc6a04`
#[derive(
Clone,
Expand Down Expand Up @@ -2804,6 +2843,7 @@ pub mod light_client_mock {
#[derive(Clone, ::ethers::contract::EthAbiType, serde::Serialize, serde::Deserialize)]
pub enum LightClientMockCalls {
UpgradeInterfaceVersion(UpgradeInterfaceVersionCall),
CurrentBlockNumber(CurrentBlockNumberCall),
DisablePermissionedProverMode(DisablePermissionedProverModeCall),
FinalizedState(FinalizedStateCall),
GenesisStakeTableState(GenesisStakeTableStateCall),
Expand Down Expand Up @@ -2841,6 +2881,11 @@ pub mod light_client_mock {
{
return Ok(Self::UpgradeInterfaceVersion(decoded));
}
if let Ok(decoded) =
<CurrentBlockNumberCall as ::ethers::core::abi::AbiDecode>::decode(data)
{
return Ok(Self::CurrentBlockNumber(decoded));
}
if let Ok(decoded) =
<DisablePermissionedProverModeCall as ::ethers::core::abi::AbiDecode>::decode(data)
{
Expand Down Expand Up @@ -2971,6 +3016,9 @@ pub mod light_client_mock {
Self::UpgradeInterfaceVersion(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Self::CurrentBlockNumber(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Self::DisablePermissionedProverMode(element) => {
::ethers::core::abi::AbiEncode::encode(element)
}
Expand Down Expand Up @@ -3030,6 +3078,7 @@ pub mod light_client_mock {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Self::UpgradeInterfaceVersion(element) => ::core::fmt::Display::fmt(element, f),
Self::CurrentBlockNumber(element) => ::core::fmt::Display::fmt(element, f),
Self::DisablePermissionedProverMode(element) => {
::core::fmt::Display::fmt(element, f)
}
Expand Down Expand Up @@ -3068,6 +3117,11 @@ pub mod light_client_mock {
Self::UpgradeInterfaceVersion(value)
}
}
impl ::core::convert::From<CurrentBlockNumberCall> for LightClientMockCalls {
fn from(value: CurrentBlockNumberCall) -> Self {
Self::CurrentBlockNumber(value)
}
}
impl ::core::convert::From<DisablePermissionedProverModeCall> for LightClientMockCalls {
fn from(value: DisablePermissionedProverModeCall) -> Self {
Self::DisablePermissionedProverMode(value)
Expand Down Expand Up @@ -3212,6 +3266,20 @@ pub mod light_client_mock {
Hash,
)]
pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String);
///Container type for all return fields from the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b`
#[derive(
Clone,
::ethers::contract::EthAbiType,
::ethers::contract::EthAbiCodec,
serde::Serialize,
serde::Deserialize,
Default,
Debug,
PartialEq,
Eq,
Hash,
)]
pub struct CurrentBlockNumberReturn(pub ::ethers::core::types::U256);
///Container type for all return fields from the `finalizedState` function with signature `finalizedState()` and selector `0x9fdb54a7`
#[derive(
Clone,
Expand Down
15 changes: 10 additions & 5 deletions contracts/src/LightClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable {
_initializeState(_genesis, _genesisStakeTableState, _stateHistoryRetentionPeriod);
}

/// @notice returns the current block number
function currentBlockNumber() public view virtual returns (uint256) {
return block.number;
}

/// @notice Use this to get the implementation contract version
/// @return majorVersion The major version of the contract
/// @return minorVersion The minor version of the contract
Expand Down Expand Up @@ -211,7 +216,7 @@ contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable {

stateHistoryRetentionPeriod = _stateHistoryRetentionPeriod;

updateStateHistory(uint64(block.number), uint64(block.timestamp), _genesis);
updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), _genesis);
}

// === State Modifying APIs ===
Expand Down Expand Up @@ -252,7 +257,7 @@ contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable {
// upon successful verification, update the latest finalized state
finalizedState = newState;

updateStateHistory(uint64(block.number), uint64(block.timestamp), newState);
updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), newState);

emit NewState(newState.viewNum, newState.blockHeight, newState.blockCommRoot);
}
Expand Down Expand Up @@ -371,16 +376,16 @@ contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable {
// 3. Provided block number is earlier than the first recorded state update
// the stateHistoryFirstIndex is used to check for the first nonZero element
if (
blockNumber > block.number || updatesCount == 0
blockNumber > currentBlockNumber() || updatesCount == 0
|| blockNumber < stateHistoryCommitments[stateHistoryFirstIndex].l1BlockHeight
) {
revert InsufficientSnapshotHistory();
}

uint256 eligibleStateUpdateBlockNumber; // the eligibleStateUpdateBlockNumber is <=
// blockNumber
// blockNumber
bool stateUpdateFound; // if an eligible block number is found in the state update history,
// then this variable is set to true
// then this variable is set to true

// Search from the most recent state update back to find the first update <= blockNumber
uint256 i = updatesCount - 1;
Expand Down
15 changes: 15 additions & 0 deletions contracts/src/LightClientArbitrum.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.0;

import { LightClient } from "./LightClient.sol";

interface ArbSys {
function arbBlockNumber() external view returns (uint256);
}

contract LightClientArbitrum is LightClient {
function currentBlockNumber() public view virtual override returns (uint256) {
return ArbSys(address(uint160(100))).arbBlockNumber();
}
}
29 changes: 29 additions & 0 deletions contracts/test/LightClientArbitrum.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import { LightClientArbitrum, ArbSys } from "../src/LightClientArbitrum.sol";

contract MockArbSys is ArbSys {
function arbBlockNumber() external pure override returns (uint256) {
return 123456;
}
}

contract LightClientArbitrumTest is Test {
LightClientArbitrum public lc;
MockArbSys mockArbsys;

function setUp() public {
vm.createSelectFork("https://arb1.arbitrum.io/rpc");
mockArbsys = new MockArbSys();
vm.etch(address(100), address(mockArbsys).code); // Replace address(100) with mock
// implementation
lc = new LightClientArbitrum();
}

function testCurrentBlockNumber() public {
assertNotEq(lc.currentBlockNumber(), block.number);
assertEq(lc.currentBlockNumber(), ArbSys(address(uint160(100))).arbBlockNumber());
}
}

0 comments on commit 29b2c00

Please sign in to comment.