mirror of
https://github.com/danog/toncontest.git
synced 2024-11-30 04:29:14 +01:00
Compiling version
This commit is contained in:
parent
f4fe489db6
commit
238fa78dcf
@ -17,12 +17,16 @@ wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMe
|
|||||||
multiSigWrapper$0 signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapper X;
|
multiSigWrapper$0 signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapper X;
|
||||||
//multiSigFuture$1 = MultiSigWrapper X;
|
//multiSigFuture$1 = MultiSigWrapper X;
|
||||||
|
|
||||||
// Message constructor for wallet storage
|
// Message constructor for wallet storagesince
|
||||||
// No seqno: we can't regenerate the hash of a stored message.
|
// No seqno: we can't regenerate the hash of a stored message.
|
||||||
// That's a tradeoff to save grams on storage (and storing the seqno would be pointless anyway,
|
// That's a tradeoff to save grams on storage (and storing the seqno would be pointless anyway,
|
||||||
// since all integrity checks were already made when the message was first stored).
|
// since all integrity checks were already made when the message was first stored).
|
||||||
//
|
//
|
||||||
storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) body:(ModeMessage X) = StoredMessage X;
|
// But do we __have to__ store the body?
|
||||||
|
// I mean, each incoming order already has the full message body, why store it if you can reuse it?
|
||||||
|
// Anyway, for now I'm storing the body. (Scratch that, it's a waste of storage, just store the hash)
|
||||||
|
//
|
||||||
|
storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) = StoredMessage X;
|
||||||
|
|
||||||
|
|
||||||
// Not doing explicit versioning here, since the structure of the storage can only change after an update of the onchain wallet code
|
// Not doing explicit versioning here, since the structure of the storage can only change after an update of the onchain wallet code
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
;; expiry <= now
|
;; expiry <= now
|
||||||
if (cs~load_uint(32) <= now()) {
|
if (cs~load_uint(32) <= now()) {
|
||||||
messages.udict_delete?(256, hash);
|
messages~udict_delete?(256, hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} until (~ ok);
|
} until (~ ok);
|
||||||
@ -45,7 +45,7 @@
|
|||||||
;; We will need the hash anyway
|
;; We will need the hash anyway
|
||||||
var hash = slice_hash(in_msg);
|
var hash = slice_hash(in_msg);
|
||||||
|
|
||||||
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 (## 256)) messages:(HashmapE 8 ^(Message X)) = Storage X;
|
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 8 ^(StoredMessage X)) = Storage X;
|
||||||
var stored_data = get_data().begin_parse();
|
var stored_data = get_data().begin_parse();
|
||||||
var (stored_seqno, min_sigs, keys, messages) = (stored_data~load_uint(32), stored_data~load_uint(4), stored_data~load_dict(), stored_data~load_dict());
|
var (stored_seqno, min_sigs, keys, messages) = (stored_data~load_uint(32), stored_data~load_uint(4), stored_data~load_dict(), stored_data~load_dict());
|
||||||
stored_data.end_parse();
|
stored_data.end_parse();
|
||||||
@ -58,18 +58,21 @@
|
|||||||
|
|
||||||
;; If old message
|
;; If old message
|
||||||
} else {
|
} else {
|
||||||
(var storedMessage, var ok) = messages.udict_get?(256, hash);
|
var (storedMessage, ok) = messages.udict_get?(256, hash);
|
||||||
;; Throw if old message and doesn't exist in db
|
;; Throw if old message and doesn't exist in db
|
||||||
throw_unless(35, ok);
|
throw_unless(35, ok);
|
||||||
|
|
||||||
|
;; storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) = StoredMessage X;
|
||||||
|
;;
|
||||||
;; Skip expiry
|
;; Skip expiry
|
||||||
storedMessage.skip_bits(32);
|
;;
|
||||||
;; No seqno: we can't regenerate the hash of a stored message.
|
;; No seqno: we can't regenerate the hash of a stored message.
|
||||||
;; That's a tradeoff to save grams on storage (and storing the seqno would be pointless anyway,
|
;; That's a tradeoff to save grams on storage (and storing the seqno would be pointless anyway,
|
||||||
;; since all integrity checks were already made when the message was first stored).
|
;; since all integrity checks were already made when the message was first stored).
|
||||||
;;
|
;;
|
||||||
;; Load signatures
|
;; Load signatures
|
||||||
var storedMessageSignatures = storedMessage.load_dict();
|
var storedMessageSignatures = storedMessage~load_ref().begin_parse().skip_bits(32).preload_dict();
|
||||||
|
storedMessage.end_parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
accept_message();
|
accept_message();
|
||||||
@ -79,15 +82,24 @@
|
|||||||
do {
|
do {
|
||||||
(idx, var signature, var ok) = signatures.udict_get_next?(4, idx);
|
(idx, var signature, var ok) = signatures.udict_get_next?(4, idx);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
(var public_key, var kok) = keys.udict_get?(4, idx);
|
var (public_key, kok) = keys.udict_get?(4, idx);
|
||||||
throw_unless(36, kok);
|
throw_unless(36, kok);
|
||||||
throw_unless(37, check_signature(hash, signature, public_key~load_uint(256)));
|
|
||||||
|
var key = public_key~load_ref().begin_parse().preload_uint(256);
|
||||||
|
var signature_cell = signature~load_ref();
|
||||||
|
var signature_slice = signature_cell.begin_parse();
|
||||||
|
var slice_copy = signature_slice;
|
||||||
|
|
||||||
|
signature_slice.end_parse();
|
||||||
|
public_key.end_parse();
|
||||||
|
|
||||||
storedMessageSignatures.udict_set_ref(4, idx, signature);
|
throw_unless(37, check_signature(hash, slice_copy, key));
|
||||||
|
|
||||||
|
storedMessageSignatures~udict_set_ref(4, idx, signature_cell);
|
||||||
}
|
}
|
||||||
} until (~ ok);
|
} until (~ ok);
|
||||||
|
|
||||||
var message = message_data~load_ref();
|
var (mode, message) = (message_data~load_uint(8), message_data~load_ref());
|
||||||
message_data.end_parse();
|
message_data.end_parse();
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
@ -99,20 +111,20 @@
|
|||||||
count += 1;
|
count += 1;
|
||||||
if (count >= min_sigs) {
|
if (count >= min_sigs) {
|
||||||
send_raw_message(message, mode);
|
send_raw_message(message, mode);
|
||||||
messages.udict_delete?(256, hash);
|
messages~udict_delete?(256, hash);
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} until (~ ok);
|
} until (~ ok);
|
||||||
|
|
||||||
;; storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) body:^(Message X) = StoredMessage X;
|
;; storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) = StoredMessage X;
|
||||||
;;
|
;;
|
||||||
;; But do we __have to__ store the body?
|
;; But do we __have to__ store the body?
|
||||||
;; I mean, each incoming order already has the full message body, why store it if you can reuse it?
|
;; I mean, each incoming order already has the full message body, why store it if you can reuse it?
|
||||||
;; Anyway, for now I'm just storing this.
|
;; Anyway, for now I'm storing the body. (Scratch that, it's a waste of storage, just store the hash)
|
||||||
;;
|
;;
|
||||||
if (count < min_sigs) {
|
if (count < min_sigs) {
|
||||||
messages.udict_set(256, hash, begin_cell().store_uint(expires_at, 32).store_dict(storedMessageSignatures).store_ref(message).end_cell());
|
messages~udict_set_ref(256, hash, begin_cell().store_uint(expires_at, 32).store_dict(storedMessageSignatures).end_cell());
|
||||||
}
|
}
|
||||||
messages = collect_garbage(messages);
|
messages = collect_garbage(messages);
|
||||||
|
|
||||||
|
@ -5,9 +5,6 @@ PROGRAM{
|
|||||||
DECLPROC store_db
|
DECLPROC store_db
|
||||||
DECLPROC recv_internal
|
DECLPROC recv_internal
|
||||||
DECLPROC recv_external
|
DECLPROC recv_external
|
||||||
DECLPROC .udict_set_ref
|
|
||||||
DECLPROC mode
|
|
||||||
DECLPROC .udict_set
|
|
||||||
85143 DECLMETHOD seqno
|
85143 DECLMETHOD seqno
|
||||||
collect_garbage PROC:<{
|
collect_garbage PROC:<{
|
||||||
-1 PUSHINT
|
-1 PUSHINT
|
||||||
@ -25,12 +22,20 @@ PROGRAM{
|
|||||||
NOW
|
NOW
|
||||||
LEQ
|
LEQ
|
||||||
IF:<{
|
IF:<{
|
||||||
|
8 PUSHPOW2
|
||||||
|
s1 s3 s3 PUXC2
|
||||||
|
DICTUDEL
|
||||||
|
DROP
|
||||||
|
}>ELSE<{
|
||||||
|
s0 s2 XCHG
|
||||||
}>
|
}>
|
||||||
}>ELSE<{
|
}>ELSE<{
|
||||||
s2 POP
|
2SWAP
|
||||||
|
DROP
|
||||||
}>
|
}>
|
||||||
SWAP
|
SWAP
|
||||||
NOT
|
NOT
|
||||||
|
s1 s2 XCHG
|
||||||
}>
|
}>
|
||||||
DROP
|
DROP
|
||||||
}>
|
}>
|
||||||
@ -46,6 +51,160 @@ PROGRAM{
|
|||||||
recv_internal PROC:<{
|
recv_internal PROC:<{
|
||||||
DROP
|
DROP
|
||||||
}>
|
}>
|
||||||
|
recv_external PROC:<{
|
||||||
|
1 LDU
|
||||||
|
SWAP
|
||||||
|
32 THROWIFNOT
|
||||||
|
DUP
|
||||||
|
1 PLDU
|
||||||
|
33 THROWIFNOT
|
||||||
|
LDDICT
|
||||||
|
DUP
|
||||||
|
32 LDU
|
||||||
|
32 LDU
|
||||||
|
s2 PUSH
|
||||||
|
NOW
|
||||||
|
LEQ
|
||||||
|
34 THROWIF
|
||||||
|
s0 s3 XCHG
|
||||||
|
HASHSU
|
||||||
|
c4 PUSH
|
||||||
|
CTOS
|
||||||
|
32 LDU
|
||||||
|
4 LDU
|
||||||
|
LDDICT
|
||||||
|
LDDICT
|
||||||
|
ENDS
|
||||||
|
s3 PUSH
|
||||||
|
NEWDICT
|
||||||
|
s0 s7 XCHG
|
||||||
|
EQUAL
|
||||||
|
IF:<{
|
||||||
|
s0 s3 XCHG
|
||||||
|
INC
|
||||||
|
}>ELSE<{
|
||||||
|
s4 s0 PUSH2
|
||||||
|
8 PUSHPOW2
|
||||||
|
DICTUGET
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
35 THROWIFNOT
|
||||||
|
LDREF
|
||||||
|
NIP
|
||||||
|
ENDS
|
||||||
|
s0 s3 XCHG
|
||||||
|
}>
|
||||||
|
ACCEPT
|
||||||
|
s0 s7 XCHG
|
||||||
|
-1 PUSHINT
|
||||||
|
UNTIL:<{
|
||||||
|
s9 PUSH
|
||||||
|
4 PUSHINT
|
||||||
|
DICTUGETNEXT
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
DUP
|
||||||
|
IF:<{
|
||||||
|
s1 s4 PUSH2
|
||||||
|
4 PUSHINT
|
||||||
|
DICTUGET
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
36 THROWIFNOT
|
||||||
|
LDREF
|
||||||
|
SWAP
|
||||||
|
CTOS
|
||||||
|
256 PLDU
|
||||||
|
s0 s4 XCHG
|
||||||
|
LDREF
|
||||||
|
DROP
|
||||||
|
DUP
|
||||||
|
CTOS
|
||||||
|
DUP
|
||||||
|
ENDS
|
||||||
|
s0 s2 XCHG
|
||||||
|
ENDS
|
||||||
|
s9 s(-1) s4 PUXC2
|
||||||
|
CHKSIGNU
|
||||||
|
37 THROWIFNOT
|
||||||
|
s1 s2 XCHG
|
||||||
|
4 PUSHINT
|
||||||
|
s3 s9 s9 PUXC2
|
||||||
|
DICTUSETREF
|
||||||
|
}>ELSE<{
|
||||||
|
s1 s8 s8 XCHG3
|
||||||
|
DROP
|
||||||
|
}>
|
||||||
|
s0 s7 XCHG
|
||||||
|
NOT
|
||||||
|
}>
|
||||||
|
DROP
|
||||||
|
s8 POP
|
||||||
|
s0 s7 XCHG
|
||||||
|
8 LDU
|
||||||
|
LDREF
|
||||||
|
ENDS
|
||||||
|
0 PUSHINT
|
||||||
|
-1 PUSHINT
|
||||||
|
UNTIL:<{
|
||||||
|
s7 PUSH
|
||||||
|
4 PUSHINT
|
||||||
|
DICTUGETNEXT
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
NULLSWAPIFNOT
|
||||||
|
s2 POP
|
||||||
|
OVER
|
||||||
|
IF:<{
|
||||||
|
s0 s2 XCHG
|
||||||
|
INC
|
||||||
|
s0 s5 PUSH2
|
||||||
|
GEQ
|
||||||
|
IF:<{
|
||||||
|
NIP
|
||||||
|
s2 s3 PUSH2
|
||||||
|
SENDRAWMSG
|
||||||
|
8 PUSHPOW2
|
||||||
|
s7 s6 s6 PUXC2
|
||||||
|
DICTUDEL
|
||||||
|
DROP
|
||||||
|
0 PUSHINT
|
||||||
|
}>ELSE<{
|
||||||
|
s6 s6 XCHG2
|
||||||
|
}>
|
||||||
|
}>ELSE<{
|
||||||
|
s0 s6 s6 XCHG3
|
||||||
|
}>
|
||||||
|
NOT
|
||||||
|
s6 s6 s0 XCHG3
|
||||||
|
}>
|
||||||
|
s1 s3 XCHG
|
||||||
|
3 BLKDROP
|
||||||
|
OVER
|
||||||
|
LESS
|
||||||
|
IF:<{
|
||||||
|
NEWC
|
||||||
|
s1 s5 XCHG
|
||||||
|
32 STU
|
||||||
|
s1 s3 XCHG
|
||||||
|
STDICT
|
||||||
|
ENDC
|
||||||
|
s0 s2 XCHG
|
||||||
|
8 PUSHPOW2
|
||||||
|
DICTUSETREF
|
||||||
|
}>ELSE<{
|
||||||
|
s3 s4 XCHG2
|
||||||
|
3 BLKDROP
|
||||||
|
}>
|
||||||
|
collect_garbage CALLDICT
|
||||||
|
s0 s2 XCHG
|
||||||
|
INC
|
||||||
|
NEWC
|
||||||
|
32 STU
|
||||||
|
4 STU
|
||||||
|
s1 s2 XCHG
|
||||||
|
STDICT
|
||||||
|
STDICT
|
||||||
|
ENDC
|
||||||
|
c4 POP
|
||||||
|
}>
|
||||||
seqno PROC:<{
|
seqno PROC:<{
|
||||||
c4 PUSH
|
c4 PUSH
|
||||||
CTOS
|
CTOS
|
||||||
|
Loading…
Reference in New Issue
Block a user