Skip to content

feat(target_chains/ton): add target address and custom payload support #2136

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

Merged
merged 3 commits into from
Nov 21, 2024
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
10 changes: 8 additions & 2 deletions target_chains/ton/contracts/contracts/Main.fc
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@
slice price_ids_slice = price_ids_cell.begin_parse();
int min_publish_time = in_msg_body~load_uint(64);
int max_publish_time = in_msg_body~load_uint(64);
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address, target_address, custom_payload);
} elseif (op == OP_PARSE_UNIQUE_PRICE_FEED_UPDATES) {
cell price_ids_cell = in_msg_body~load_ref();
slice price_ids_slice = price_ids_cell.begin_parse();
int publish_time = in_msg_body~load_uint(64);
int max_staleness = in_msg_body~load_uint(64);
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address, target_address, custom_payload);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
40 changes: 9 additions & 31 deletions target_chains/ton/contracts/contracts/Pyth.fc
Original file line number Diff line number Diff line change
Expand Up @@ -328,60 +328,38 @@ cell create_price_feed_cell_chain(tuple price_feeds) {
return result;
}

() send_price_feeds_response(tuple price_feeds, int msg_value, int op, slice sender_address) impure {
() send_price_feeds_response(tuple price_feeds, int msg_value, int op, slice sender_address, slice target_address, slice custom_payload) impure {
;; Build response cell with price feeds
builder response = begin_cell()
.store_uint(op, 32) ;; Response op
.store_uint(price_feeds.tlen(), 8); ;; Number of price feeds

;; Create and store price feed cell chain
cell price_feeds_cell = create_price_feed_cell_chain(price_feeds);
response = response.store_ref(price_feeds_cell);

;; Build the complete message cell (https://docs.ton.org/v3/documentation/smart-contracts/message-management/sending-messages#message-layout)
cell msg = begin_cell()
.store_uint(0x18, 6)
.store_slice(sender_address)
.store_coins(0) ;; Will fill in actual amount after fee calculations
.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_ref(response.end_cell())
.end_cell();
cell custom_payload_cell = begin_cell().store_slice(custom_payload).end_cell();
response = response.store_ref(price_feeds_cell).store_slice(sender_address).store_ref(custom_payload_cell);

int num_price_feeds = price_feeds.tlen();

;; Number of cells in the message
;; - 2 cells: msg + response
int cells = 2 + num_price_feeds;

;; Bit layout per TL-B spec (https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb):
;; - 6 bits: optimized way of serializing the tag and the first 4 fields
;; - 256 bits: owner address
;; - 128 bits: coins (VarUInteger 16) from grams$_ amount:(VarUInteger 16) = Grams
;; - 107 bits: MSG_SERIALIZE_BITS
;; - PRICE_FEED_BITS * num_price_feeds: space for each price feed
int bits = 6 + 256 + 128 + MSG_SERIALIZE_BITS + (PRICE_FEED_BITS * num_price_feeds);
int fwd_fee = get_forward_fee(cells, bits, WORKCHAIN);

;; Calculate all fees
int compute_fee = get_compute_fee(WORKCHAIN, get_gas_consumed());
int update_fee = single_update_fee * price_feeds.tlen();

;; Calculate total fees and remaining excess
int total_fees = compute_fee + update_fee + fwd_fee;
int total_fees = compute_fee + update_fee;
int excess = msg_value - total_fees;

;; Send response message back to sender with exact excess amount
send_raw_message(begin_cell()
.store_uint(0x18, 6)
.store_slice(sender_address)
.store_slice(target_address)
.store_coins(excess)
.store_uint(1, MSG_SERIALIZE_BITS)
.store_ref(response.end_cell())
.end_cell(),
0);
}

() parse_price_feed_updates(int msg_value, slice update_data_slice, slice price_ids_slice, int min_publish_time, int max_publish_time, slice sender_address) impure {
() parse_price_feed_updates(int msg_value, slice update_data_slice, slice price_ids_slice, int min_publish_time, int max_publish_time, slice sender_address, slice target_address, slice custom_payload) impure {
load_data();

;; Load price_ids tuple
Expand All @@ -393,10 +371,10 @@ cell create_price_feed_cell_chain(tuple price_feeds) {
}

tuple price_feeds = parse_price_feeds_from_data(msg_value, update_data_slice, price_ids, min_publish_time, max_publish_time, false);
send_price_feeds_response(price_feeds, msg_value, OP_PARSE_PRICE_FEED_UPDATES, sender_address);
send_price_feeds_response(price_feeds, msg_value, OP_PARSE_PRICE_FEED_UPDATES, sender_address, target_address, custom_payload);
}

() parse_unique_price_feed_updates(int msg_value, slice update_data_slice, slice price_ids_slice, int publish_time, int max_staleness, slice sender_address) impure {
() parse_unique_price_feed_updates(int msg_value, slice update_data_slice, slice price_ids_slice, int publish_time, int max_staleness, slice sender_address, slice target_address, slice custom_payload) impure {
load_data();

;; Load price_ids tuple
Expand All @@ -408,7 +386,7 @@ cell create_price_feed_cell_chain(tuple price_feeds) {
}

tuple price_feeds = parse_price_feeds_from_data(msg_value, update_data_slice, price_ids, publish_time, publish_time + max_staleness, true);
send_price_feeds_response(price_feeds, msg_value, OP_PARSE_UNIQUE_PRICE_FEED_UPDATES, sender_address);
send_price_feeds_response(price_feeds, msg_value, OP_PARSE_UNIQUE_PRICE_FEED_UPDATES, sender_address, target_address, custom_payload);
}

() update_price_feeds(int msg_value, slice data) impure {
Expand Down
1 change: 0 additions & 1 deletion target_chains/ton/contracts/contracts/common/gas.fc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
int get_compute_fee(int workchain, int gas_used) asm(gas_used workchain) "GETGASFEE";
int get_gas_consumed() asm "GASCONSUMED";
int get_forward_fee(int cells, int bits, int workchain) asm(cells bits workchain) "GETFORWARDFEE";


;; 1 update: 262,567 gas
Expand Down
10 changes: 8 additions & 2 deletions target_chains/ton/contracts/contracts/tests/PythTest.fc
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@
slice price_ids_slice = price_ids_cell.begin_parse();
int min_publish_time = in_msg_body~load_uint(64);
int max_publish_time = in_msg_body~load_uint(64);
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address, target_address, custom_payload);
} elseif (op == OP_PARSE_UNIQUE_PRICE_FEED_UPDATES) {
cell price_ids_cell = in_msg_body~load_ref();
slice price_ids_slice = price_ids_cell.begin_parse();
int publish_time = in_msg_body~load_uint(64);
int max_staleness = in_msg_body~load_uint(64);
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address, target_address, custom_payload);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
10 changes: 8 additions & 2 deletions target_chains/ton/contracts/contracts/tests/PythTestUpgraded.fc
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,19 @@
slice price_ids_slice = price_ids_cell.begin_parse();
int min_publish_time = in_msg_body~load_uint(64);
int max_publish_time = in_msg_body~load_uint(64);
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_price_feed_updates(msg_value, data_slice, price_ids_slice, min_publish_time, max_publish_time, sender_address, target_address, custom_payload);
} elseif (op == OP_PARSE_UNIQUE_PRICE_FEED_UPDATES) {
cell price_ids_cell = in_msg_body~load_ref();
slice price_ids_slice = price_ids_cell.begin_parse();
int publish_time = in_msg_body~load_uint(64);
int max_staleness = in_msg_body~load_uint(64);
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address);
slice target_address = in_msg_body~load_msg_addr();
cell custom_payload_cell = in_msg_body~load_ref();
slice custom_payload = custom_payload_cell.begin_parse();
parse_unique_price_feed_updates(msg_value, data_slice, price_ids_slice, publish_time, max_staleness, sender_address, target_address, custom_payload);
} else {
throw(0xffff); ;; Throw exception for unknown op
}
Expand Down
Loading
Loading