From c84e1d138e714f1addaefb825a11ead556ccf2a1 Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 13 Nov 2024 17:52:22 +0200 Subject: [PATCH 1/4] move gas-service logic to versioned --- move/gas_service/sources/events.move | 89 ++++++++++++ move/gas_service/sources/gas_service.move | 130 ++++++------------ .../sources/versioned/gas_service_v0.move | 91 +++++++++++- .../interface_gas_service_events.json | 4 + 4 files changed, 227 insertions(+), 87 deletions(-) create mode 100644 move/gas_service/sources/events.move create mode 100644 test/testdata/interface_gas_service_events.json diff --git a/move/gas_service/sources/events.move b/move/gas_service/sources/events.move new file mode 100644 index 00000000..00b196db --- /dev/null +++ b/move/gas_service/sources/events.move @@ -0,0 +1,89 @@ +module gas_service::events; + +use std::ascii::String; +use sui::event; + +// ------ +// Events +// ------ +public struct GasPaid has copy, drop { + sender: address, + destination_chain: String, + destination_address: String, + payload_hash: address, + value: u64, + refund_address: address, + params: vector, +} + +public struct GasAdded has copy, drop { + message_id: String, + value: u64, + refund_address: address, + params: vector, +} + +public struct Refunded has copy, drop { + message_id: String, + value: u64, + refund_address: address, +} + +public struct GasCollected has copy, drop { + receiver: address, + value: u64, +} + +// Package Functions +public(package) fun gas_paid( + sender: address, + destination_chain: String, + destination_address: String, + payload_hash: address, + value: u64, + refund_address: address, + params: vector, +) { + event::emit(GasPaid { + sender, + destination_chain, + destination_address, + payload_hash, + value, + refund_address, + params, + }); +} + +public(package) fun gas_added( + message_id: String, + value: u64, + refund_address: address, + params: vector, +) { + event::emit(GasAdded { + message_id, + value, + refund_address, + params, + }); +} + +public(package) fun refunded( + message_id: String, + value: u64, + refund_address: address, +) { + event::emit(Refunded { + message_id, + value, + refund_address, + }); +} + +public(package) fun gas_collected(receiver: address, value: u64) { + event::emit(GasCollected { + receiver, + value, + }); +} diff --git a/move/gas_service/sources/gas_service.move b/move/gas_service/sources/gas_service.move index 12f9e3bb..9bee412a 100644 --- a/move/gas_service/sources/gas_service.move +++ b/move/gas_service/sources/gas_service.move @@ -2,9 +2,7 @@ module gas_service::gas_service; use gas_service::gas_service_v0::{Self, GasService_v0}; use std::ascii::{Self, String}; -use sui::address; use sui::coin::Coin; -use sui::event; use sui::hash::keccak256; use sui::sui::SUI; use sui::versioned::{Self, Versioned}; @@ -27,37 +25,6 @@ public struct GasCollectorCap has key, store { id: UID, } -// ------ -// Events -// ------ -public struct GasPaid has copy, drop { - sender: address, - destination_chain: String, - destination_address: String, - payload_hash: address, - value: u64, - refund_address: address, - params: vector, -} - -public struct GasAdded has copy, drop { - message_id: String, - value: u64, - refund_address: address, - params: vector, -} - -public struct Refunded has copy, drop { - message_id: String, - value: u64, - refund_address: address, -} - -public struct GasCollected has copy, drop { - receiver: address, - value: u64, -} - // ----- // Setup // ----- @@ -98,8 +65,10 @@ macro fun value_mut( // Public Functions // ---------------- /// Pay gas for a contract call. -/// This function is called by the channel that wants to pay gas for a contract call. -/// It can also be called by the user to pay gas for a contract call, while setting the sender as the channel ID. +/// This function is called by the channel that wants to pay gas for a contract +/// call. +/// It can also be called by the user to pay gas for a contract call, while +/// setting the sender as the channel ID. public fun pay_gas( self: &mut GasService, coin: Coin, @@ -110,24 +79,22 @@ public fun pay_gas( refund_address: address, params: vector, ) { - let coin_value = coin.value(); - self.value_mut!(b"pay_gas").put(coin); - - let payload_hash = address::from_bytes(keccak256(&payload)); - - event::emit(GasPaid { - sender, - destination_chain, - destination_address, - payload_hash, - value: coin_value, - refund_address, - params, - }) + self + .value_mut!(b"pay_gas") + .pay_gas( + coin, + sender, + destination_chain, + destination_address, + payload, + refund_address, + params, + ); } /// Add gas for an existing cross-chain contract call. -/// This function can be called by a user who wants to add gas for a contract call with insufficient gas. +/// This function can be called by a user who wants to add gas for a contract +/// call with insufficient gas. public fun add_gas( self: &mut GasService, coin: Coin, @@ -135,15 +102,14 @@ public fun add_gas( refund_address: address, params: vector, ) { - let coin_value = coin.value(); - self.value_mut!(b"add_gas").put(coin); - - event::emit(GasAdded { - message_id, - value: coin_value, - refund_address, - params, - }); + self + .value_mut!(b"add_gas") + .add_gas( + coin, + message_id, + refund_address, + params, + ); } public fun collect_gas( @@ -153,15 +119,13 @@ public fun collect_gas( amount: u64, ctx: &mut TxContext, ) { - transfer::public_transfer( - self.value_mut!(b"collect_gas").take(amount, ctx), - receiver, - ); - - event::emit(GasCollected { - receiver, - value: amount, - }); + self + .value_mut!(b"collect_gas") + .collect_gas( + receiver, + amount, + ctx, + ) } public fun refund( @@ -172,29 +136,25 @@ public fun refund( amount: u64, ctx: &mut TxContext, ) { - transfer::public_transfer( - self.value_mut!(b"refund").take(amount, ctx), - receiver, - ); - - event::emit(Refunded { - message_id, - value: amount, - refund_address: receiver, - }); + self + .value_mut!(b"refund") + .refund( + message_id, + receiver, + amount, + ctx, + ); } // ----------------- // Private Functions // ----------------- fun version_control(): VersionControl { - version_control::new( - vector[ - vector[b"pay_gas", b"add_gas", b"collect_gas", b"refund"].map!( - |function_name| function_name.to_ascii_string(), - ), - ], - ) + version_control::new(vector[ + vector[b"pay_gas", b"add_gas", b"collect_gas", b"refund"].map!( + |function_name| function_name.to_ascii_string(), + ), + ]) } // ----- diff --git a/move/gas_service/sources/versioned/gas_service_v0.move b/move/gas_service/sources/versioned/gas_service_v0.move index 400ad3d4..c1bcd83a 100644 --- a/move/gas_service/sources/versioned/gas_service_v0.move +++ b/move/gas_service/sources/versioned/gas_service_v0.move @@ -1,7 +1,11 @@ module gas_service::gas_service_v0; +use gas_service::events; +use std::ascii::String; +use sui::address; use sui::balance::{Self, Balance}; use sui::coin::{Self, Coin}; +use sui::hash::keccak256; use sui::sui::SUI; use version_control::version_control::VersionControl; @@ -27,11 +31,94 @@ public(package) fun version_control(self: &GasService_v0): &VersionControl { &self.version_control } -public(package) fun put(self: &mut GasService_v0, coin: Coin) { +public(package) fun pay_gas( + self: &mut GasService_v0, + coin: Coin, + sender: address, + destination_chain: String, + destination_address: String, + payload: vector, + refund_address: address, + params: vector, +) { + let coin_value = coin.value(); + self.put(coin); + + let payload_hash = address::from_bytes(keccak256(&payload)); + + events::gas_paid( + sender, + destination_chain, + destination_address, + payload_hash, + coin_value, + refund_address, + params, + ); +} + +public(package) fun add_gas( + self: &mut GasService_v0, + coin: Coin, + message_id: String, + refund_address: address, + params: vector, +) { + let coin_value = coin.value(); + self.put(coin); + + events::gas_added( + message_id, + coin_value, + refund_address, + params, + ); +} + +public(package) fun collect_gas( + self: &mut GasService_v0, + receiver: address, + amount: u64, + ctx: &mut TxContext, +) { + transfer::public_transfer( + self.take(amount, ctx), + receiver, + ); + + events::gas_collected( + receiver, + amount, + ); +} + +public(package) fun refund( + self: &mut GasService_v0, + message_id: String, + receiver: address, + amount: u64, + ctx: &mut TxContext, +) { + transfer::public_transfer( + self.take(amount, ctx), + receiver, + ); + + events::refunded( + message_id, + amount, + receiver, + ); +} + +// ----------------- +// Private Functions +// ----------------- +fun put(self: &mut GasService_v0, coin: Coin) { coin::put(&mut self.balance, coin); } -public(package) fun take( +fun take( self: &mut GasService_v0, amount: u64, ctx: &mut TxContext, diff --git a/test/testdata/interface_gas_service_events.json b/test/testdata/interface_gas_service_events.json new file mode 100644 index 00000000..0b162a70 --- /dev/null +++ b/test/testdata/interface_gas_service_events.json @@ -0,0 +1,4 @@ +{ + "structs": {}, + "publicFunctions": {} +} From e832a63996744b9255d84d81ea1036e57af6bead Mon Sep 17 00:00:00 2001 From: Foivos Date: Tue, 19 Nov 2024 16:11:19 +0200 Subject: [PATCH 2/4] added a method to pay gas using a message ticket --- move/example/Move.toml | 2 +- move/gas_service/Move.lock | 24 +++++++++++++++-- move/gas_service/Move.toml | 1 + move/gas_service/sources/gas_service.move | 18 +++++++++++++ .../sources/versioned/gas_service_v0.move | 26 +++++++++++++++++++ 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/move/example/Move.toml b/move/example/Move.toml index e988646d..71a64333 100644 --- a/move/example/Move.toml +++ b/move/example/Move.toml @@ -5,8 +5,8 @@ edition = "2024.beta" [dependencies] Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet-v1.35.2" } -AxelarGateway = { local = "../axelar_gateway" } GasService = { local = "../gas_service" } +AxelarGateway = { local = "../axelar_gateway" } Utils = { local = "../utils" } VersionControl = { local = "../version_control" } ITS = { local = "../its" } diff --git a/move/gas_service/Move.lock b/move/gas_service/Move.lock index f9b3f51b..16161b14 100644 --- a/move/gas_service/Move.lock +++ b/move/gas_service/Move.lock @@ -2,13 +2,25 @@ [move] version = 3 -manifest_digest = "C29AEC3A18805EA1C5A2FCA5811D6AAD6BE44E394A8FDF0B02FB34D3409F4D3E" -deps_digest = "3C4103934B1E040BB6B23F1D610B4EF9F2F1166A50A104EADCF77467C004C600" +manifest_digest = "C04CC08DC1212FBCB4F5A869F32A9607A3C3E3586BC3BEFC0C0F1DBD3CE563CE" +deps_digest = "060AD7E57DFB13104F21BE5F5C3759D03F0553FC3229247D9A7A6B45F50D03A3" dependencies = [ + { id = "AxelarGateway", name = "AxelarGateway" }, { id = "Sui", name = "Sui" }, { id = "VersionControl", name = "VersionControl" }, ] +[[move.package]] +id = "AxelarGateway" +source = { local = "../axelar_gateway" } + +dependencies = [ + { id = "MoveStdlib", name = "MoveStdlib" }, + { id = "Sui", name = "Sui" }, + { id = "Utils", name = "Utils" }, + { id = "VersionControl", name = "VersionControl" }, +] + [[move.package]] id = "MoveStdlib" source = { git = "https://github.com/MystenLabs/sui.git", rev = "mainnet-v1.35.2", subdir = "crates/sui-framework/packages/move-stdlib" } @@ -21,6 +33,14 @@ dependencies = [ { id = "MoveStdlib", name = "MoveStdlib" }, ] +[[move.package]] +id = "Utils" +source = { local = "../utils" } + +dependencies = [ + { id = "Sui", name = "Sui" }, +] + [[move.package]] id = "VersionControl" source = { local = "../version_control" } diff --git a/move/gas_service/Move.toml b/move/gas_service/Move.toml index 1e804f9b..c83e94eb 100644 --- a/move/gas_service/Move.toml +++ b/move/gas_service/Move.toml @@ -6,6 +6,7 @@ edition = "2024.beta" [dependencies] Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet-v1.35.2" } VersionControl = { local = "../version_control" } +AxelarGateway = { local = "../axelar_gateway" } [addresses] gas_service = "0xa2" diff --git a/move/gas_service/sources/gas_service.move b/move/gas_service/sources/gas_service.move index 9bee412a..8d5b443b 100644 --- a/move/gas_service/sources/gas_service.move +++ b/move/gas_service/sources/gas_service.move @@ -1,5 +1,6 @@ module gas_service::gas_service; +use axelar_gateway::message_ticket::MessageTicket; use gas_service::gas_service_v0::{Self, GasService_v0}; use std::ascii::{Self, String}; use sui::coin::Coin; @@ -112,6 +113,23 @@ public fun add_gas( ); } +public fun pay_gas_for_message_ticket( + self: &mut GasService, + message_ticket: &MessageTicket, + coin: Coin, + refund_address: address, + params: vector, +) { + self + .value_mut!(b"pay_gas_for_message_ticket") + .pay_gas_for_message_ticket( + message_ticket, + coin, + refund_address, + params, + ); +} + public fun collect_gas( self: &mut GasService, _: &GasCollectorCap, diff --git a/move/gas_service/sources/versioned/gas_service_v0.move b/move/gas_service/sources/versioned/gas_service_v0.move index c1bcd83a..727fe00a 100644 --- a/move/gas_service/sources/versioned/gas_service_v0.move +++ b/move/gas_service/sources/versioned/gas_service_v0.move @@ -1,5 +1,6 @@ module gas_service::gas_service_v0; +use axelar_gateway::message_ticket::MessageTicket; use gas_service::events; use std::ascii::String; use sui::address; @@ -75,6 +76,31 @@ public(package) fun add_gas( ); } +public(package) fun pay_gas_for_message_ticket( + self: &mut GasService_v0, + message_ticket: &MessageTicket, + coin: Coin, + refund_address: address, + params: vector, +) { + let coin_value = coin.value(); + self.put(coin); + + let payload_hash = address::from_bytes( + keccak256(&message_ticket.payload()), + ); + + events::gas_paid( + message_ticket.source_id(), + message_ticket.destination_chain(), + message_ticket.destination_address(), + payload_hash, + coin_value, + refund_address, + params, + ); +} + public(package) fun collect_gas( self: &mut GasService_v0, receiver: address, From 273013c7b8c67434e25e1ccdfeca4e3d52a368d2 Mon Sep 17 00:00:00 2001 From: Foivos Date: Tue, 19 Nov 2024 19:21:56 +0200 Subject: [PATCH 3/4] remode pay_gas entirely --- .changeset/fair-dots-explode.md | 5 ++ move/example/sources/gmp/gmp.move | 17 +++--- move/example/sources/its/its.move | 5 +- move/gas_service/sources/gas_service.move | 57 +++++++------------ .../sources/versioned/gas_service_v0.move | 28 +-------- 5 files changed, 37 insertions(+), 75 deletions(-) create mode 100644 .changeset/fair-dots-explode.md diff --git a/.changeset/fair-dots-explode.md b/.changeset/fair-dots-explode.md new file mode 100644 index 00000000..1a624436 --- /dev/null +++ b/.changeset/fair-dots-explode.md @@ -0,0 +1,5 @@ +--- +'@axelar-network/axelar-cgp-sui': minor +--- + +Paying for gas now requires the message ticket instead of the call information. diff --git a/move/example/sources/gmp/gmp.move b/move/example/sources/gmp/gmp.move index 06408989..c95cce56 100644 --- a/move/example/sources/gmp/gmp.move +++ b/move/example/sources/gmp/gmp.move @@ -77,20 +77,19 @@ public fun send_call( coin: Coin, params: vector, ) { - gas_service.pay_gas( - coin, - sui::object::id_address(&singleton.channel), - destination_chain, - destination_address, - payload, - refund_address, - params, - ); + let message_ticket = gateway::prepare_message( &singleton.channel, destination_chain, destination_address, payload, + ); + + gas_service.pay_gas( + &message_ticket, + coin, + refund_address, + params, ); gateway.send_message(message_ticket); diff --git a/move/example/sources/its/its.move b/move/example/sources/its/its.move index 48f0b94a..ca1b2806 100644 --- a/move/example/sources/its/its.move +++ b/move/example/sources/its/its.move @@ -267,11 +267,8 @@ fun pay_gas_and_send_message( gas_params: vector, ) { gas_service.pay_gas( + &message_ticket, gas, - message_ticket.source_id(), - message_ticket.destination_chain(), - message_ticket.destination_address(), - message_ticket.payload(), refund_address, gas_params, ); diff --git a/move/gas_service/sources/gas_service.move b/move/gas_service/sources/gas_service.move index 8d5b443b..3eb8338f 100644 --- a/move/gas_service/sources/gas_service.move +++ b/move/gas_service/sources/gas_service.move @@ -65,34 +65,6 @@ macro fun value_mut( // ---------------- // Public Functions // ---------------- -/// Pay gas for a contract call. -/// This function is called by the channel that wants to pay gas for a contract -/// call. -/// It can also be called by the user to pay gas for a contract call, while -/// setting the sender as the channel ID. -public fun pay_gas( - self: &mut GasService, - coin: Coin, - sender: address, - destination_chain: String, - destination_address: String, - payload: vector, - refund_address: address, - params: vector, -) { - self - .value_mut!(b"pay_gas") - .pay_gas( - coin, - sender, - destination_chain, - destination_address, - payload, - refund_address, - params, - ); -} - /// Add gas for an existing cross-chain contract call. /// This function can be called by a user who wants to add gas for a contract /// call with insufficient gas. @@ -113,7 +85,12 @@ public fun add_gas( ); } -public fun pay_gas_for_message_ticket( +/// Pay gas for a contract call. +/// This function is called by the channel that wants to pay gas for a contract +/// call. +/// It can also be called by the user to pay gas for a contract call, while +/// setting the sender as the channel ID. +public fun pay_gas( self: &mut GasService, message_ticket: &MessageTicket, coin: Coin, @@ -121,8 +98,8 @@ public fun pay_gas_for_message_ticket( params: vector, ) { self - .value_mut!(b"pay_gas_for_message_ticket") - .pay_gas_for_message_ticket( + .value_mut!(b"pay_gas") + .pay_gas( message_ticket, coin, refund_address, @@ -238,14 +215,22 @@ fun test_pay_gas() { let digest = ctx.digest(); let value = (((digest[0] as u16) << 8) | (digest[1] as u16) as u64) + 1; let c: Coin = coin::mint_for_testing(value, ctx); + let channel = axelar_gateway::channel::new(ctx); + let destination_chain = b"destination chain".to_ascii_string(); + let destination_address = b"destination address".to_ascii_string(); + let payload = b"payload"; + + let ticket = axelar_gateway::gateway::prepare_message( + &channel, + destination_chain, + destination_address, + payload, + ); service.pay_gas( + &ticket, c, ctx.sender(), - std::ascii::string(b"destination chain"), - std::ascii::string(b"destination address"), - vector[], - ctx.sender(), vector[], ); @@ -253,6 +238,8 @@ fun test_pay_gas() { cap.destroy_cap(); service.destroy(); + channel.destroy(); + sui::test_utils::destroy(ticket); } #[test] diff --git a/move/gas_service/sources/versioned/gas_service_v0.move b/move/gas_service/sources/versioned/gas_service_v0.move index 727fe00a..e3bea124 100644 --- a/move/gas_service/sources/versioned/gas_service_v0.move +++ b/move/gas_service/sources/versioned/gas_service_v0.move @@ -32,32 +32,6 @@ public(package) fun version_control(self: &GasService_v0): &VersionControl { &self.version_control } -public(package) fun pay_gas( - self: &mut GasService_v0, - coin: Coin, - sender: address, - destination_chain: String, - destination_address: String, - payload: vector, - refund_address: address, - params: vector, -) { - let coin_value = coin.value(); - self.put(coin); - - let payload_hash = address::from_bytes(keccak256(&payload)); - - events::gas_paid( - sender, - destination_chain, - destination_address, - payload_hash, - coin_value, - refund_address, - params, - ); -} - public(package) fun add_gas( self: &mut GasService_v0, coin: Coin, @@ -76,7 +50,7 @@ public(package) fun add_gas( ); } -public(package) fun pay_gas_for_message_ticket( +public(package) fun pay_gas( self: &mut GasService_v0, message_ticket: &MessageTicket, coin: Coin, From 690834b4c662b437ce96034193022c898f471d12 Mon Sep 17 00:00:00 2001 From: Foivos Date: Wed, 20 Nov 2024 15:11:11 +0200 Subject: [PATCH 4/4] move pay_gas above add_gas --- move/gas_service/sources/gas_service.move | 36 +++++++++---------- .../sources/versioned/gas_service_v0.move | 30 ++++++++-------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/move/gas_service/sources/gas_service.move b/move/gas_service/sources/gas_service.move index 3eb8338f..c27a5659 100644 --- a/move/gas_service/sources/gas_service.move +++ b/move/gas_service/sources/gas_service.move @@ -65,43 +65,43 @@ macro fun value_mut( // ---------------- // Public Functions // ---------------- -/// Add gas for an existing cross-chain contract call. -/// This function can be called by a user who wants to add gas for a contract -/// call with insufficient gas. -public fun add_gas( +/// Pay gas for a contract call. +/// This function is called by the channel that wants to pay gas for a contract +/// call. +/// It can also be called by the user to pay gas for a contract call, while +/// setting the sender as the channel ID. +public fun pay_gas( self: &mut GasService, + message_ticket: &MessageTicket, coin: Coin, - message_id: String, refund_address: address, params: vector, ) { self - .value_mut!(b"add_gas") - .add_gas( + .value_mut!(b"pay_gas") + .pay_gas( + message_ticket, coin, - message_id, refund_address, params, ); } -/// Pay gas for a contract call. -/// This function is called by the channel that wants to pay gas for a contract -/// call. -/// It can also be called by the user to pay gas for a contract call, while -/// setting the sender as the channel ID. -public fun pay_gas( +/// Add gas for an existing cross-chain contract call. +/// This function can be called by a user who wants to add gas for a contract +/// call with insufficient gas. +public fun add_gas( self: &mut GasService, - message_ticket: &MessageTicket, coin: Coin, + message_id: String, refund_address: address, params: vector, ) { self - .value_mut!(b"pay_gas") - .pay_gas( - message_ticket, + .value_mut!(b"add_gas") + .add_gas( coin, + message_id, refund_address, params, ); diff --git a/move/gas_service/sources/versioned/gas_service_v0.move b/move/gas_service/sources/versioned/gas_service_v0.move index e3bea124..84a676d5 100644 --- a/move/gas_service/sources/versioned/gas_service_v0.move +++ b/move/gas_service/sources/versioned/gas_service_v0.move @@ -32,43 +32,43 @@ public(package) fun version_control(self: &GasService_v0): &VersionControl { &self.version_control } -public(package) fun add_gas( +public(package) fun pay_gas( self: &mut GasService_v0, + message_ticket: &MessageTicket, coin: Coin, - message_id: String, refund_address: address, params: vector, ) { let coin_value = coin.value(); self.put(coin); - events::gas_added( - message_id, + let payload_hash = address::from_bytes( + keccak256(&message_ticket.payload()), + ); + + events::gas_paid( + message_ticket.source_id(), + message_ticket.destination_chain(), + message_ticket.destination_address(), + payload_hash, coin_value, refund_address, params, ); } -public(package) fun pay_gas( +public(package) fun add_gas( self: &mut GasService_v0, - message_ticket: &MessageTicket, coin: Coin, + message_id: String, refund_address: address, params: vector, ) { let coin_value = coin.value(); self.put(coin); - let payload_hash = address::from_bytes( - keccak256(&message_ticket.payload()), - ); - - events::gas_paid( - message_ticket.source_id(), - message_ticket.destination_chain(), - message_ticket.destination_address(), - payload_hash, + events::gas_added( + message_id, coin_value, refund_address, params,