Ton
118 строк · 4.2 Кб
1#include "stdlib.fc";
2#include "bridge-config.fc";
3#include "message_utils.fc";
4
5cell load_data() inline_ref {
6var ds = get_data().begin_parse();
7return ds~load_dict();
8}
9
10() save_data(cell external_votings) impure inline_ref {
11var st = begin_cell().store_dict(external_votings).end_cell();
12set_data(st);
13}
14
15() vote_on_external_chain(slice s_addr, int query_id, int voting_id, slice signature) impure {
16cell external_votings = load_data();
17(_, int oracles_address, cell oracles) = get_bridge_config();
18(int wc, int addr) = parse_std_addr(s_addr);
19throw_if(301, wc + 1);
20(slice key, int found?) = oracles.udict_get?(256, addr);
21throw_unless(304, found?);
22
23(slice old_voting_data, int voting_found?) = external_votings.udict_get?(256, voting_id);
24cell signatures = new_dict();
25if (voting_found?) {
26(_, int old_oracles_address, signatures) = (old_voting_data~load_uint(32),
27old_voting_data~load_uint(256),
28old_voting_data~load_dict());
29if (old_oracles_address != oracles_address) {
30signatures = new_dict();
31}
32}
33int secp_key = key~load_uint(256);
34int success? = signatures~udict_add?(256, secp_key, signature);
35throw_unless(324, success?);
36builder new_voting_data = begin_cell()
37.store_uint(now(), 32)
38.store_uint(oracles_address, 256)
39.store_dict(signatures);
40external_votings~udict_set_builder(256, voting_id, new_voting_data);
41
42save_data(external_votings);
43return send_receipt_message(s_addr, 0x10000 + 5, query_id, voting_id, 0, 64);
44}
45
46() remove_outdated_votings(slice s_addr, int query_id, slice external_ids) impure {
47cell external_votings = load_data();
48
49int bound = now() - 60 * 60 * 24 * 7;
50while (~ external_ids.slice_empty?()) {
51if (external_ids.slice_data_empty?()) {
52external_ids = external_ids.preload_ref().begin_parse();
53}
54int voting_id = external_ids~load_uint(256);
55(cell external_votings', slice voting, int voting_found?) = external_votings.udict_delete_get?(256, voting_id);
56if (voting_found?) {
57int last_update = voting~load_uint(32);
58if (bound > last_update) {
59;; remove only old votings
60external_votings = external_votings';
61}
62}
63}
64
65save_data(external_votings);
66return send_receipt_message(s_addr, 0x10000 + 6, query_id, 0, 0, 64); ;; thanks
67}
68
69() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure {
70var cs = in_msg_cell.begin_parse();
71var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
72if (flags & 1) {
73;; ignore all bounced messages
74return ();
75}
76slice s_addr = cs~load_msg_addr();
77if (in_msg.slice_empty?()) {
78;; inbound message has empty body
79return ();
80}
81int op = in_msg~load_uint(32);
82if (op == 0) {
83return ();
84}
85int query_id = in_msg~load_uint(64);
86
87if (op == 5) { ;; submit signatures
88int voting_id = in_msg~load_uint(256);
89slice signature = in_msg~load_bits(520);
90return vote_on_external_chain(s_addr, query_id, voting_id, signature);
91}
92
93if (op == 6) { ;; remove old swaps
94return remove_outdated_votings(s_addr, query_id, in_msg);
95}
96}
97
98(tuple) get_external_voting_data(int voting_id) method_id {
99cell external_votings = load_data();
100(slice voting_data, int found?) = external_votings.udict_get?(256, voting_id);
101throw_unless(309, found?);
102(int time, int old_oracles_address, cell signatures) = (voting_data~load_uint(32),
103voting_data~load_uint(256),
104voting_data~load_dict());
105tuple list = null();
106
107int secp_key = -1;
108do {
109(secp_key, slice sig, int found?) = signatures.udict_get_next?(256, secp_key);
110if (found?) {
111(int r, int s, int v) = (sig~load_uint(256),
112sig~load_uint(256),
113sig~load_uint(8));
114list = cons( pair( secp_key, triple(r,s,v)), list);
115}
116} until (~ found?);
117return (list);
118}
119