-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat(lightclient): add CommitClientStatus message to persist client s… #4859
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ use depolama::{RawStore, StorageExt}; | |
use frissitheto::{UpgradeError, UpgradeMsg}; | ||
use ibc_union_msg::{ | ||
lightclient::{ | ||
QueryMsg as LightClientQuery, Status, UpdateStateResponse, VerifyCreationResponse, | ||
QueryMsg as LightClientQuery, UpdateStateResponse, VerifyCreationResponse, | ||
VerifyCreationResponseEvent, | ||
}, | ||
module::{ExecuteMsg as ModuleMsg, IbcUnionMsg}, | ||
|
@@ -28,7 +28,8 @@ use ibc_union_msg::{ | |
use ibc_union_spec::{ | ||
path::{ | ||
commit_packets, BatchPacketsPath, BatchReceiptsPath, ChannelPath, ClientStatePath, | ||
ConnectionPath, ConsensusStatePath, COMMITMENT_MAGIC, COMMITMENT_MAGIC_ACK, | ||
ClientStatusPath, ConnectionPath, ConsensusStatePath, COMMITMENT_MAGIC, | ||
COMMITMENT_MAGIC_ACK, Status, | ||
}, | ||
Channel, ChannelId, ChannelState, ClientId, Connection, ConnectionId, ConnectionState, Packet, | ||
Timestamp, | ||
|
@@ -596,6 +597,28 @@ pub fn execute( | |
.add_attribute("relayer", relayer), | ||
)) | ||
} | ||
ExecuteMsg::CommitClientStatus(msg) => { | ||
let status = query_light_client::<Status>( | ||
deps.as_ref(), | ||
client_impl(deps.as_ref(), msg.client_id)?, | ||
LightClientQuery::GetStatus { | ||
client_id: msg.client_id, | ||
}, | ||
)?; | ||
|
||
let status_bytes = (status as u8).to_le_bytes(); | ||
|
||
store_commit( | ||
deps.branch(), | ||
&ClientStatusPath { | ||
client_id: msg.client_id, | ||
} | ||
.key(), | ||
&commit(status_bytes), | ||
); | ||
|
||
Ok(Response::default()) | ||
} | ||
} | ||
} | ||
|
||
|
@@ -2171,6 +2194,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractErr | |
)?; | ||
Ok(to_json_binary(&status)?) | ||
} | ||
QueryMsg::GetCommittedStatus { client_id, .. } => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the field is unused, remove it from the msg |
||
let commit = read_commit(deps, &ClientStatusPath { client_id }.key()); | ||
Ok(to_json_binary(&commit)?) | ||
} | ||
QueryMsg::GetChannels { contract } => { | ||
let contract = deps.api.addr_validate(&contract)?; | ||
let channels = deps.storage.read::<ContractChannels>(&contract)?; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ voyager-primitives = { workspace = true } | |
ibc-union-spec = { workspace = true, features = ["ethabi", "schemars", "serde"] } | ||
|
||
[features] | ||
default = [] | ||
default = ["serde"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove, do not add default features |
||
|
||
bincode = ["dep:bincode", "voyager-primitives/bincode", "unionlabs/bincode"] | ||
ethabi = ["dep:alloy-sol-types", "unionlabs/ethabi"] | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3,6 +3,7 @@ use sha3::{Digest, Keccak256}; | |||||
use unionlabs::primitives::{Bytes, H256, U256}; | ||||||
use voyager_primitives::IbcStorePathKey; | ||||||
|
||||||
|
||||||
#[cfg(feature = "ethabi")] | ||||||
use crate::Packet; | ||||||
use crate::{ | ||||||
|
@@ -34,6 +35,7 @@ pub const CONNECTIONS: U256 = U256::from_limbs([2, 0, 0, 0]); | |||||
pub const CHANNELS: U256 = U256::from_limbs([3, 0, 0, 0]); | ||||||
pub const PACKETS: U256 = U256::from_limbs([4, 0, 0, 0]); | ||||||
pub const PACKET_ACKS: U256 = U256::from_limbs([5, 0, 0, 0]); | ||||||
pub const CLIENT_STATUS: U256 = U256::from_limbs([6, 0, 0, 0]); | ||||||
|
||||||
#[cfg(feature = "ethabi")] | ||||||
#[must_use] | ||||||
|
@@ -60,6 +62,7 @@ pub enum StorePath { | |||||
Channel(ChannelPath), | ||||||
BatchReceipts(BatchReceiptsPath), | ||||||
BatchPackets(BatchPacketsPath), | ||||||
ClientStatus(ClientStatusPath), | ||||||
} | ||||||
|
||||||
impl StorePath { | ||||||
|
@@ -72,6 +75,7 @@ impl StorePath { | |||||
StorePath::Channel(path) => path.key(), | ||||||
StorePath::BatchReceipts(path) => path.key(), | ||||||
StorePath::BatchPackets(path) => path.key(), | ||||||
StorePath::ClientStatus(path) => path.key(), | ||||||
} | ||||||
} | ||||||
} | ||||||
|
@@ -265,3 +269,41 @@ impl IbcStorePathKey for BatchPacketsPath { | |||||
|
||||||
type Value = H256; | ||||||
} | ||||||
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] | ||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] | ||||||
#[serde(deny_unknown_fields, rename_all = "snake_case")] | ||||||
#[repr(u8)] | ||||||
pub enum Status { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this type should be under ibc_union_spec::types, and reexported at the crate root with the rest of the types. |
||||||
Active = 1, | ||||||
Expired = 2, | ||||||
Frozen = 3, | ||||||
} | ||||||
|
||||||
/// Represents the path to a client's committed status (Active, Expired, etc.) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] | ||||||
#[cfg_attr( | ||||||
feature = "serde", | ||||||
derive(serde::Serialize, serde::Deserialize), | ||||||
serde(rename_all = "snake_case", deny_unknown_fields) | ||||||
)] | ||||||
pub struct ClientStatusPath { | ||||||
pub client_id: ClientId, | ||||||
} | ||||||
|
||||||
impl ClientStatusPath { | ||||||
#[must_use] | ||||||
pub fn key(&self) -> H256 { | ||||||
Keccak256::new() | ||||||
.chain_update(CLIENT_STATUS.to_be_bytes()) | ||||||
.chain_update(U256::from(self.client_id.get()).to_be_bytes()) | ||||||
.finalize() | ||||||
.into() | ||||||
} | ||||||
} | ||||||
|
||||||
impl IbcStorePathKey for ClientStatusPath { | ||||||
type Spec = IbcUnion; | ||||||
type Value = u8; // repr(u8) status stored as raw byte | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should move the status enum into this crate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -367,6 +367,30 @@ impl Module { | |
|
||
Ok(commitment.flatten()) | ||
} | ||
|
||
#[instrument( | ||
skip_all, | ||
fields( | ||
chain_id = %self.chain_id, | ||
%height, | ||
%client_id | ||
) | ||
)] | ||
async fn query_client_status( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rename this to |
||
&self, | ||
height: Height, | ||
client_id: ClientId, | ||
) -> RpcResult<Option<u8>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
let status = self | ||
.query_smart::<_, u8>( | ||
&ibc_union_msg::query::QueryMsg::GetStatus { client_id }, | ||
Some(height), | ||
) | ||
.await?; | ||
|
||
Ok(status) | ||
} | ||
|
||
} | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
|
@@ -503,6 +527,10 @@ impl StateModuleServer<IbcUnion> for Module { | |
.query_batch_receipts(at, path.batch_hash) | ||
.await | ||
.map(into_value), | ||
StorePath::ClientStatus(path) => self | ||
.query_client_status(at, path.client_id) | ||
.await | ||
.map(into_value), | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -566,6 +566,23 @@ impl Module { | |
None::<()>, | ||
)) | ||
} | ||
|
||
#[instrument(skip_all,fields(chain_id = %self.chain_id, %height, %client_id))] | ||
async fn query_client_status( | ||
&self, | ||
height: Height, | ||
client_id: ClientId, | ||
) -> RpcResult<Option<u8>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should return |
||
let status = self | ||
.query_smart::<_, u8>( | ||
&ibc_union_msg::query::QueryMsg::GetStatus { client_id }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the wrong query; you need to use |
||
Some(height), | ||
) | ||
.await?; | ||
|
||
Ok(status) | ||
} | ||
|
||
} | ||
|
||
fn mk_windows(mut latest_height: u64, window: u64) -> Vec<(BlockNumberOrTag, BlockNumberOrTag)> { | ||
|
@@ -633,6 +650,10 @@ impl StateModuleServer<IbcUnion> for Module { | |
.query_batch_packets(at, path.batch_hash) | ||
.await | ||
.map(into_value), | ||
StorePath::ClientStatus(path) => self | ||
.query_client_status(at, path.client_id) | ||
.await | ||
.map(into_value), | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
store the bytes directly, as a
U256
value