-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ton
committed
Sep 30, 2019
1 parent
fd7a8de
commit ecb3e06
Showing
37 changed files
with
581 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
;; Heavy-duty wallet for mass transfers (e.g., for cryptocurrency exchanges) | ||
;; accepts orders for up to 254 internal messages (transfers) in one external message | ||
|
||
() recv_internal(slice in_msg) impure { | ||
;; do nothing for internal messages | ||
} | ||
|
||
() recv_external(slice in_msg) impure { | ||
var signature = in_msg~load_bits(512); | ||
var cs = in_msg; | ||
var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); | ||
throw_if(35, valid_until <= now()); | ||
var ds = get_data().begin_parse(); | ||
var (stored_seqno, stored_subwallet, public_key) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256)); | ||
ds.end_parse(); | ||
throw_unless(33, msg_seqno == stored_seqno); | ||
throw_unless(34, subwallet_id == stored_subwallet); | ||
throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); | ||
var dict = cs~load_dict(); | ||
cs.end_parse(); | ||
accept_message(); | ||
int i = -1; | ||
do { | ||
(i, var cs, var f) = dict.idict_get_next?(16, i); | ||
if (f) { | ||
var mode = cs~load_uint(8); | ||
send_raw_message(cs~load_ref(), mode); | ||
} | ||
} until (~ f); | ||
set_data(begin_cell() | ||
.store_uint(stored_seqno + 1, 32) | ||
.store_uint(stored_subwallet, 32) | ||
.store_uint(public_key, 256) | ||
.end_cell()); | ||
} | ||
|
||
;; Get methods | ||
|
||
int seqno() method_id { | ||
return get_data().begin_parse().preload_uint(32); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
;; Heavy-duty wallet for mass transfers (e.g., for cryptocurrency exchanges) | ||
;; accepts orders for up to 254 internal messages (transfers) in one external message | ||
;; this version does not use seqno for replay protection; instead, it remembers all recent query_ids | ||
;; in this way several external messages with different query_id can be sent in parallel | ||
|
||
() recv_internal(slice in_msg) impure { | ||
;; do nothing for internal messages | ||
} | ||
|
||
() recv_external(slice in_msg) impure { | ||
var signature = in_msg~load_bits(512); | ||
var cs = in_msg; | ||
var (subwallet_id, query_id) = (cs~load_uint(32), cs~load_uint(64)); | ||
var bound = (now() << 32); | ||
throw_if(35, query_id < bound); | ||
var ds = get_data().begin_parse(); | ||
var (stored_subwallet, last_cleaned, public_key, old_queries) = (ds~load_uint(32), ds~load_uint(64), ds~load_uint(256), ds~load_dict()); | ||
ds.end_parse(); | ||
(_, var found?) = old_queries.udict_get?(64, query_id); | ||
throw_if(32, found?); | ||
throw_unless(34, subwallet_id == stored_subwallet); | ||
throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); | ||
var dict = cs~load_dict(); | ||
cs.end_parse(); | ||
accept_message(); | ||
int i = -1; | ||
do { | ||
(i, var cs, var f) = dict.idict_get_next?(16, i); | ||
if (f) { | ||
var mode = cs~load_uint(8); | ||
send_raw_message(cs~load_ref(), mode); | ||
} | ||
} until (~ f); | ||
bound -= (64 << 32); ;; clean up records expired more than 64 seconds ago | ||
old_queries~udict_set_builder(64, query_id, begin_cell()); | ||
var queries = old_queries; | ||
do { | ||
var (old_queries', i, _, f) = old_queries.udict_delete_get_min(64); | ||
f~touch(); | ||
if (f) { | ||
f = (i < bound); | ||
} | ||
if (f) { | ||
old_queries = old_queries'; | ||
last_cleaned = i; | ||
} | ||
} until (~ f); | ||
set_data(begin_cell() | ||
.store_uint(stored_subwallet, 32) | ||
.store_uint(last_cleaned, 64) | ||
.store_uint(public_key, 256) | ||
.store_dict(old_queries) | ||
.end_cell()); | ||
} | ||
|
||
;; Get methods | ||
|
||
;; returns -1 for processed queries, 0 for unprocessed, 1 for unknown (forgotten) | ||
int processed?(int query_id) method_id { | ||
var ds = get_data().begin_parse(); | ||
var (_, last_cleaned, _, old_queries) = (ds~load_uint(32), ds~load_uint(64), ds~load_uint(256), ds~load_dict()); | ||
ds.end_parse(); | ||
(_, var found) = old_queries.udict_get?(64, query_id); | ||
return found ? true : - (query_id <= last_cleaned); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#!/usr/bin/env fift -s | ||
"TonUtil.fif" include | ||
|
||
{ ."usage: " @' $0 type ." <filename-base> <subwallet-id> <seqno> <order-file> [<savefile>]" cr | ||
."Creates a request with up to 254 orders loaded from <order-file> to high-load (sub)wallet created by new-highload-wallet.fif, with private key loaded from file <filename-base>.pk " | ||
."and address from <filename-base><subwallet-id>.addr, and saves it into <savefile>.boc ('wallet-query.boc' by default)" cr | ||
."<order-file> is a text file with lines `SEND <dest-addr> <amount>`" cr 1 halt | ||
} : usage | ||
$# dup 4 < swap 5 > or ' usage if | ||
|
||
$1 =: file-base | ||
$2 parse-int dup 32 fits ' usage ifnot =: subwallet-id // parse subwallet-id | ||
{ subwallet-id (.) $+ } : +subwallet | ||
$3 parse-int =: seqno | ||
$4 =: order-file | ||
def? $5 { @' $5 } { "wallet-query" } cond constant savefile | ||
3 constant send-mode // mode for SENDRAWMSG: +1 - sender pays fees, +2 - ignore errors | ||
60 constant timeout // external message expires in 60 seconds | ||
|
||
file-base +subwallet +".addr" load-address | ||
2dup 2constant wallet_addr | ||
."Source wallet address = " 2dup .addr cr 6 .Addr cr | ||
file-base +".pk" load-keypair nip constant wallet_pk | ||
|
||
variable orders dictnew orders ! | ||
variable order# order# 0! | ||
// c -- | ||
{ <s order# @ dup 254 >= abort"more than 254 orders" | ||
orders @ 16 udict!+ not abort"cannot add order to dictionary" | ||
orders ! order# 1+! | ||
} : add-order | ||
// b body -- b' | ||
{ tuck <s 2dup s-fits? not rot over 1 i, -rot | ||
{ drop swap ref, } { s, nip } cond | ||
} : append-msg-body | ||
// ng wc addr bounce body -- c | ||
{ <b b{01} s, rot 1 i, b{000100} s, 2swap addr, rot Gram, | ||
0 9 64 32 + + 1+ u, swap append-msg-body b> | ||
} : create-int-msg | ||
// ng wc addr bnc -- | ||
{ ."Transferring " 3 roll .GR ."to account " | ||
-rot 2dup 4 pick 7 + .Addr ." = " .addr ." bounce=" . cr | ||
} : .transfer | ||
// addr$ ng -- c | ||
{ swap parse-smc-addr // ng wc addr bnc | ||
2over 2over .transfer | ||
<b 0 32 u, b> create-int-msg | ||
} : create-simple-transfer | ||
// c m -- c' | ||
{ <b swap 8 u, swap ref, b> } : create-order | ||
|
||
// addr$ ng -- | ||
{ create-simple-transfer send-mode create-order add-order } : send | ||
{ bl word bl word $>GR send } : SEND | ||
|
||
// parse order file | ||
order-file include | ||
|
||
// create external message | ||
<b subwallet-id 32 i, now timeout + 32 u, seqno 32 u, orders @ dict, b> | ||
dup ."signing message: " <s csr. cr | ||
dup hash wallet_pk ed25519_sign_uint | ||
<b b{1000100} s, wallet_addr addr, 0 Gram, b{00} s, | ||
swap B, swap <s s, b> | ||
dup ."resulting external message: " <s csr. cr | ||
2 boc+>B dup Bx. cr | ||
savefile +".boc" tuck B>file | ||
."(Saved to file " type .")" cr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/usr/bin/env fift -s | ||
"TonUtil.fif" include | ||
"Asm.fif" include | ||
|
||
{ ."usage: " @' $0 type ." <workchain-id> <subwallet-id> [<filename-base>]" cr | ||
."Creates a new high-load wallet in the specified workchain, with the controlling private key saved to or loaded from <filename-base>.pk " | ||
."('new-wallet.pk' by default)" cr | ||
."<subwallet-id> is the 32-bit identifier of this subwallet among all controlled by the same private key" cr 1 halt | ||
} : usage | ||
$# 2- -2 and ' usage if | ||
|
||
$1 parse-workchain-id =: wc // set workchain id from command line argument | ||
$2 parse-int dup =: subwallet-id // parse subwallet-id | ||
32 fits ' usage ifnot | ||
{ subwallet-id (.) $+ } : +subwallet | ||
def? $3 { @' $3 } { "new-wallet" } cond constant file-base | ||
|
||
."Creating new high-load wallet in workchain " wc . | ||
."with subwallet id " subwallet-id . cr | ||
|
||
// Create new high-load wallet; source code included from `highload-wallet-code.fif` | ||
"highload-wallet-code.fif" include | ||
// code | ||
<b 0 32 u, subwallet-id 32 i, | ||
file-base +".pk" load-generate-keypair | ||
constant wallet_pk | ||
B, | ||
b> // data | ||
null // no libraries | ||
<b b{0011} s, 3 roll ref, rot ref, swap dict, b> // create StateInit | ||
dup ."StateInit: " <s csr. cr | ||
dup hash wc swap 2dup 2constant wallet_addr | ||
."new wallet address = " 2dup .addr cr | ||
2dup file-base +subwallet +".addr" save-address-verbose | ||
."Non-bounceable address (for init): " 2dup 7 .Addr cr | ||
."Bounceable address (for later access): " 6 .Addr cr | ||
<b subwallet-id 32 i, -1 32 i, 0 32 u, false 1 i, b> | ||
dup ."signing message: " <s csr. cr | ||
dup hash wallet_pk ed25519_sign_uint rot | ||
<b b{1000100} s, wallet_addr addr, b{000010} s, swap <s s, b{0} s, swap B, swap <s s, b> | ||
dup ."External message for initialization is " <s csr. cr | ||
2 boc+>B dup Bx. cr | ||
file-base +subwallet +"-query.boc" tuck B>file | ||
."(Saved wallet creating query to file " type .")" cr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
include(CMakeFindDependencyMacro) | ||
#TODO: write all external dependencies | ||
include("${CMAKE_CURRENT_LIST_DIR}/TonlibTargets.cmake") |
Oops, something went wrong.