Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LightClientArbitrum #2423

Merged
merged 5 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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) {
Sneh1999 marked this conversation as resolved.
Show resolved Hide resolved
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) {
Sneh1999 marked this conversation as resolved.
Show resolved Hide resolved
return ArbSys(address(uint160(100))).arbBlockNumber();
Sneh1999 marked this conversation as resolved.
Show resolved Hide resolved
}
}
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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this is important because foundry doesnt support arbitrum pre-compiles so we have to mock them in tests

// implementation
lc = new LightClientArbitrum();
}

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