diff --git a/move/move-ibc/sources/acknowledge_packet.move b/move/move-ibc/sources/acknowledge_packet.move index d67bd1c827..83a217cb25 100644 --- a/move/move-ibc/sources/acknowledge_packet.move +++ b/move/move-ibc/sources/acknowledge_packet.move @@ -1,6 +1,7 @@ module ibc::acknowledge_packet { use ibc::packet::{Self, Packet}; + use std::string::{String}; use ibc::channel; use ibc::engine; use ibc::commitment; @@ -11,6 +12,7 @@ module ibc::acknowledge_packet { use std::vector; public entry fun acknowledge_packet( + client_type: String, port_id: address, packet_source_channels: vector, packet_destination_channels: vector, @@ -66,6 +68,7 @@ module ibc::acknowledge_packet { let err = ibc::verify_commitment( + client_type, client_id, proof_height, proof, diff --git a/move/move-ibc/sources/channel_handshake.move b/move/move-ibc/sources/channel_handshake.move index 8188a7ed9b..44571c2636 100644 --- a/move/move-ibc/sources/channel_handshake.move +++ b/move/move-ibc/sources/channel_handshake.move @@ -1,11 +1,10 @@ module ibc::channel_handshake { + use std::string::{String}; use ibc::ibc; use ibc::dispatcher; use ibc::engine; use ibc::helpers; - use std::string::String; - public entry fun channel_open_init( port_id: address, counterparty_port_id: vector, @@ -28,6 +27,7 @@ module ibc::channel_handshake { } public entry fun channel_open_try( + client_type: String, port_id: address, connection_id: u32, counterparty_channel_id: u32, @@ -39,6 +39,7 @@ module ibc::channel_handshake { ) { let channel_id = ibc::channel_open_try( + client_type, port_id, connection_id, counterparty_channel_id, @@ -57,6 +58,7 @@ module ibc::channel_handshake { } public entry fun channel_open_ack( + client_type: String, port_id: address, channel_id: u32, counterparty_version: String, @@ -65,6 +67,7 @@ module ibc::channel_handshake { proof_height: u64 ) { ibc::channel_open_ack( + client_type, port_id, channel_id, counterparty_version, @@ -85,12 +88,19 @@ module ibc::channel_handshake { } public entry fun channel_open_confirm( + client_type: String, port_id: address, channel_id: u32, proof_ack: vector, proof_height: u64 ) { - ibc::channel_open_confirm(port_id, channel_id, proof_ack, proof_height); + ibc::channel_open_confirm( + client_type, + port_id, + channel_id, + proof_ack, + proof_height + ); engine::dispatch(helpers::pack_channel_open_confirm_params(channel_id)); diff --git a/move/move-ibc/sources/cometbls_light_client.move b/move/move-ibc/sources/cometbls_lc.move similarity index 99% rename from move/move-ibc/sources/cometbls_light_client.move rename to move/move-ibc/sources/cometbls_lc.move index 0335136b77..e2fd2f8cd7 100644 --- a/move/move-ibc/sources/cometbls_light_client.move +++ b/move/move-ibc/sources/cometbls_lc.move @@ -1,4 +1,4 @@ -module ibc::light_client { +module ibc::cometbls_lc { use std::vector; use std::bcs; use std::string::{Self}; @@ -436,7 +436,7 @@ module ibc::light_client { fun test_decode_consensus() { let buf = x"0000000000000000000000000000000000000000000000001810cfdefbacb17df5631a5398a5443f5c858e3f8d4ffb2ddd5fa325d9f825572e1a0d302f7c9c092f4975ab7e75a677f43efebf53e0ec05460d2cf55506ad08d6b05254f96a500d"; - let consensus = decode_consensus_state(buf); + let _consensus = decode_consensus_state(buf); } fun encode_consensus_state(cs: &ConsensusState): vector { diff --git a/move/move-ibc/sources/ibc.move b/move/move-ibc/sources/ibc.move index 7bc015cd53..1cc2780433 100644 --- a/move/move-ibc/sources/ibc.move +++ b/move/move-ibc/sources/ibc.move @@ -273,6 +273,7 @@ module ibc::ibc { let (client_state, consensus_state) = light_client::create_client( + client_type, &get_ibc_signer(), client_id, client_state, @@ -280,7 +281,7 @@ module ibc::ibc { ); // TODO(aeryz): fetch these status from proper exported consts - assert!(light_client::status(client_id) == 0, E_CLIENT_NOT_ACTIVE); + assert!(light_client::status(client_type, client_id) == 0, E_CLIENT_NOT_ACTIVE); // Update commitments table::upsert( @@ -289,7 +290,7 @@ module ibc::ibc { client_state ); - let latest_height = light_client::latest_height(client_id); + let latest_height = light_client::latest_height(client_type, client_id); table::upsert( &mut store.commitments, @@ -344,6 +345,7 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_init` was generated. public entry fun connection_open_try( + client_type: String, counterparty_client_id: u32, counterparty_connection_id: u32, client_id: u32, @@ -378,6 +380,7 @@ module ibc::ibc { // Verify the connection state let err = verify_connection_state( + client_type, connection, proof_height, proof_init, @@ -408,6 +411,7 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_try` was generated. public entry fun connection_open_ack( + client_type: String, connection_id: u32, counterparty_connection_id: u32, proof_try: vector, @@ -438,6 +442,7 @@ module ibc::ibc { // Verify the connection state let err = verify_connection_state( + client_type, connection, proof_height, proof_try, @@ -475,7 +480,10 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_ack` was generated. public entry fun connection_open_confirm( - connection_id: u32, proof_ack: vector, proof_height: u64 + client_type: String, + connection_id: u32, + proof_ack: vector, + proof_height: u64 ) acquires IBCStore { let store = borrow_global_mut(get_vault_addr()); @@ -504,6 +512,7 @@ module ibc::ibc { // Verify the connection state let err = verify_connection_state( + client_type, connection, proof_height, proof_ack, @@ -535,7 +544,7 @@ module ibc::ibc { /// the client update data. The light client just needs to make sure altering this data can NEVER make it /// transition to an invalid state. public entry fun update_client( - client_id: u32, client_message: vector + client_type: String, client_id: u32, client_message: vector ) acquires IBCStore { let store = borrow_global_mut(get_vault_addr()); @@ -547,18 +556,13 @@ module ibc::ibc { E_CLIENT_NOT_FOUND ); - if (light_client::check_for_misbehaviour(client_id, client_message)) { - event::emit( - SubmitMisbehaviour { - client_id, - client_type: string::utf8(CLIENT_TYPE_COMETBLS) - } - ); + if (light_client::check_for_misbehaviour(client_type, client_id, client_message)) { + event::emit(SubmitMisbehaviour { client_id, client_type: client_type }); return }; let (client_state, consensus_states, heights) = - light_client::update_client(client_id, client_message); + light_client::update_client(client_type, client_id, client_message); let heights_len = vector::length(&heights); @@ -585,13 +589,7 @@ module ibc::ibc { hash::sha2_256(*vector::borrow(&consensus_states, i)) ); - event::emit( - ClientUpdated { - client_id, - client_type: string::utf8(CLIENT_TYPE_COMETBLS), - height - } - ); + event::emit(ClientUpdated { client_id, client_type: client_type, height }); i = i + 1; }; @@ -606,7 +604,7 @@ module ibc::ibc { /// * `misbehaviour`: Light client defined misbehaviour data. It's the responsibility of the caller to gather and encode /// the correct data. The light client MUST detect any invalid misbehaviors and ignore those. public entry fun submit_misbehaviour( - client_id: u32, misbehaviour: vector + client_type: String, client_id: u32, misbehaviour: vector ) acquires IBCStore { let store = borrow_global_mut(get_vault_addr()); @@ -618,14 +616,9 @@ module ibc::ibc { E_CLIENT_NOT_FOUND ); - light_client::report_misbehaviour(client_id, misbehaviour); + light_client::report_misbehaviour(client_type, client_id, misbehaviour); - event::emit( - SubmitMisbehaviour { - client_id, - client_type: string::utf8(CLIENT_TYPE_COMETBLS) - } - ); + event::emit(SubmitMisbehaviour { client_id, client_type: client_type }); } /// Execute the init phase of the channel handshake. `T` is the witness type of the target module that is @@ -712,6 +705,7 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_init` was generated. public fun channel_open_try( + client_type: String, port_id: address, connection_id: u32, counterparty_channel_id: u32, @@ -737,6 +731,7 @@ module ibc::ibc { let err = verify_channel_state( + client_type, client_id, proof_height, proof_init, @@ -820,6 +815,7 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_try` was generated. public fun channel_open_ack( + client_type: String, port_id: address, channel_id: u32, counterparty_version: String, @@ -855,6 +851,7 @@ module ibc::ibc { let err = verify_channel_state( + client_type, client_id, proof_height, proof_try, @@ -894,6 +891,7 @@ module ibc::ibc { /// by the light client (`client_id`). /// * `proof_height`: The height at when `proof_ack` was generated. public fun channel_open_confirm( + client_type: String, port_id: address, channel_id: u32, proof_ack: vector, @@ -926,6 +924,7 @@ module ibc::ibc { let err = verify_channel_state( + client_type, client_id, proof_height, proof_ack, @@ -1058,6 +1057,7 @@ module ibc::ibc { } public(friend) fun timeout_packet( + client_type: String, port_id: address, packet_source_channel: u32, packet_destination_channel: u32, @@ -1086,14 +1086,21 @@ module ibc::ibc { let client_id = ensure_connection_state(channel::connection_id(&channel)); let proof_timestamp = - light_client::get_timestamp_at_height(client_id, proof_height); + light_client::get_timestamp_at_height(client_type, client_id, proof_height); assert!(proof_timestamp != 0, E_LATEST_TIMESTAMP_NOT_FOUND); let commitment_key = commitment::batch_receipts_commitment_key( destination_channel, commitment::commit_packet(&packet) ); - let err = verify_absent_commitment(client_id, proof_height, proof, commitment_key); + let err = + verify_absent_commitment( + client_type, + client_id, + proof_height, + proof, + commitment_key + ); assert!(err == 0, err); if (packet::timeout_timestamp(&packet) != 0) { @@ -1156,13 +1163,15 @@ module ibc::ibc { } #[view] - public fun client_state(client_id: u32): vector { - light_client::get_client_state(client_id) + public fun client_state(client_type: String, client_id: u32): vector { + light_client::get_client_state(client_type, client_id) } #[view] - public fun consensus_state(client_id: u32, revision_height: u64): vector { - light_client::get_consensus_state(client_id, revision_height) + public fun consensus_state( + client_type: String, client_id: u32, revision_height: u64 + ): vector { + light_client::get_consensus_state(client_type, client_id, revision_height) } #[view] @@ -1313,6 +1322,7 @@ module ibc::ibc { } fun verify_connection_state( + client_type: String, connection: &ConnectionEnd, height: u64, proof: vector, @@ -1320,6 +1330,7 @@ module ibc::ibc { counterparty_connection: ConnectionEnd ): u64 { light_client::verify_membership( + client_type, connection_end::client_id(connection), height, proof, @@ -1329,13 +1340,21 @@ module ibc::ibc { } public fun verify_commitment( + client_type: String, client_id: u32, height: u64, proof: vector, path: vector, commitment: vector ): u64 { - light_client::verify_membership(client_id, height, proof, path, commitment) + light_client::verify_membership( + client_type, + client_id, + height, + proof, + path, + commitment + ) } public fun generate_connection_identifier(): u32 acquires IBCStore { @@ -1435,6 +1454,7 @@ module ibc::ibc { } fun verify_channel_state( + client_type: String, client_id: u32, height: u64, proof: vector, @@ -1442,6 +1462,7 @@ module ibc::ibc { channel: Channel ): u64 { light_client::verify_membership( + client_type, client_id, height, proof, @@ -1460,12 +1481,13 @@ module ibc::ibc { } fun verify_absent_commitment( + client_type: String, clientId: u32, height: u64, proof: vector, path: vector ): u64 { - light_client::verify_non_membership(clientId, height, proof, path) + light_client::verify_non_membership(client_type, clientId, height, proof, path) } fun address_to_string(addr: address): String { diff --git a/move/move-ibc/sources/light_client.move b/move/move-ibc/sources/light_client.move new file mode 100644 index 0000000000..ef9677dd23 --- /dev/null +++ b/move/move-ibc/sources/light_client.move @@ -0,0 +1,151 @@ +module ibc::light_client { + use ibc::cometbls_lc; + use ibc::statelens_lc; + use std::string::{Self, String}; + + const E_UNKNOWN_CLIENT_TYPE: u64 = 1; + + public fun create_client( + client_type: String, + ibc_signer: &signer, + client_id: u32, + client_state_bytes: vector, + consensus_state_bytes: vector + ): (vector, vector) { + if (string::bytes(&client_type) == &b"cometbls") { + let (client_state, consensus_state) = + cometbls_lc::create_client( + ibc_signer, + client_id, + client_state_bytes, + consensus_state_bytes + ); + return (client_state, consensus_state) + } else if (string::bytes(&client_type) == &b"statelens") { + let (client_state, consensus_state) = + statelens_lc::create_client( + ibc_signer, + client_id, + client_state_bytes, + consensus_state_bytes + ); + return (client_state, consensus_state) + }; + abort E_UNKNOWN_CLIENT_TYPE + + } + + public fun status(client_type: String, client_id: u32): u64 { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::status(client_id) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::status(client_id) + }; + abort E_UNKNOWN_CLIENT_TYPE + + } + + public fun latest_height(client_type: String, client_id: u32): u64 { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::latest_height(client_id) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::latest_height(client_id) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun check_for_misbehaviour( + client_type: String, client_id: u32, header: vector + ): bool { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::check_for_misbehaviour(client_id, header) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::check_for_misbehaviour(client_id, header) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun update_client( + client_type: String, client_id: u32, client_msg: vector + ): (vector, vector>, vector) { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::update_client(client_id, client_msg) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::update_client(client_id, client_msg) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun report_misbehaviour( + client_type: String, client_id: u32, misbehaviour: vector + ) { + if (string::bytes(&client_type) == &b"cometbls") { + cometbls_lc::report_misbehaviour(client_id, misbehaviour) + } else if (string::bytes(&client_type) == &b"statelens") { + statelens_lc::report_misbehaviour(client_id, misbehaviour) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun get_timestamp_at_height( + client_type: String, client_id: u32, height: u64 + ): u64 { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::get_timestamp_at_height(client_id, height) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::get_timestamp_at_height(client_id, height) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun get_client_state(client_type: String, client_id: u32): vector { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::get_client_state(client_id) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::get_client_state(client_id) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun get_consensus_state( + client_type: String, client_id: u32, height: u64 + ): vector { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::get_consensus_state(client_id, height) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::get_consensus_state(client_id, height) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun verify_membership( + client_type: String, + client_id: u32, + height: u64, + proof: vector, + key: vector, + value: vector + ): u64 { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::verify_membership(client_id, height, proof, key, value) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::verify_membership(client_id, height, proof, key, value) + }; + abort E_UNKNOWN_CLIENT_TYPE + } + + public fun verify_non_membership( + client_type: String, + client_id: u32, + height: u64, + proof: vector, + path: vector + ): u64 { + if (string::bytes(&client_type) == &b"cometbls") { + return cometbls_lc::verify_non_membership(client_id, height, proof, path) + } else if (string::bytes(&client_type) == &b"statelens") { + return statelens_lc::verify_non_membership(client_id, height, proof, path) + }; + abort E_UNKNOWN_CLIENT_TYPE + } +} diff --git a/move/move-ibc/sources/recv_packet.move b/move/move-ibc/sources/recv_packet.move index ca14aaee41..90d8146892 100644 --- a/move/move-ibc/sources/recv_packet.move +++ b/move/move-ibc/sources/recv_packet.move @@ -1,5 +1,6 @@ module ibc::recv_packet { use ibc::packet::{Self, Packet}; + use std::string::{String}; use ibc::channel; use ibc::engine; use ibc::commitment; @@ -18,6 +19,7 @@ module ibc::recv_packet { /// Note that any sanity check failures will result in this function to be aborted in order for caller's /// storage to be reverted. This will result in acks won't be able to written. public entry fun recv_packet( + client_type: String, port_id: address, packet_source_channels: vector, packet_destination_channels: vector, @@ -46,10 +48,17 @@ module ibc::recv_packet { i = i + 1; }; - process_receive(packets, proof_height, proof, false); + process_receive( + client_type, + packets, + proof_height, + proof, + false + ); } public fun process_receive( + client_type: String, packets: vector, proof_height: u64, proof: vector, @@ -83,6 +92,7 @@ module ibc::recv_packet { let err = ibc::verify_commitment( + client_type, client_id, proof_height, proof, diff --git a/move/move-ibc/sources/state_lens_lc.move b/move/move-ibc/sources/state_lens_lc.move new file mode 100644 index 0000000000..ee3a9ec16f --- /dev/null +++ b/move/move-ibc/sources/state_lens_lc.move @@ -0,0 +1,67 @@ +module ibc::statelens_lc { + use std::vector; + + public fun create_client( + _ibc_signer: &signer, + _client_id: u32, + _client_state_bytes: vector, + _consensus_state_bytes: vector + ): (vector, vector) { + (vector::empty(), vector::empty()) + } + + public fun latest_height(_client_id: u32): u64 { + 0 + } + + public fun update_client( + _client_id: u32, _client_msg: vector + ): (vector, vector>, vector) { + (vector::empty(), vector::empty(), vector::empty()) + } + + public fun report_misbehaviour( + _client_id: u32, _misbehaviour: vector + ) {} + + public fun verify_membership( + _client_id: u32, + _height: u64, + _proof: vector, + _key: vector, + _value: vector + ): u64 { + 0 + } + + public fun verify_non_membership( + _client_id: u32, + _height: u64, + _proof: vector, + _path: vector + ): u64 { + 0 + } + + public fun status(_client_id: u32): u64 { + 0 + } + + public fun get_timestamp_at_height(_client_id: u32, _height: u64): u64 { + 0 + } + + public fun get_client_state(_client_id: u32): vector { + vector::empty() + } + + public fun get_consensus_state(_client_id: u32, _height: u64): vector { + vector::empty() + } + + public fun check_for_misbehaviour( + _client_id: u32, _header: vector + ): bool { + false + } +} diff --git a/move/move-ibc/sources/timeout_packet.move b/move/move-ibc/sources/timeout_packet.move index ac82e3371a..a702c12f00 100644 --- a/move/move-ibc/sources/timeout_packet.move +++ b/move/move-ibc/sources/timeout_packet.move @@ -4,8 +4,10 @@ module ibc::timeout_packet { use ibc::dispatcher; use ibc::helpers; use ibc::ibc; + use std::string::{String}; public entry fun timeout_packet( + client_type: String, port_id: address, packet_source_channel: u32, packet_destination_channel: u32, @@ -18,6 +20,7 @@ module ibc::timeout_packet { ) { let packet = ibc::timeout_packet( + client_type, port_id, packet_source_channel, packet_destination_channel,