1
0
mirror of https://github.com/danog/toncontest.git synced 2024-11-30 04:29:14 +01:00
This commit is contained in:
Daniil Gentili 2019-10-04 19:09:10 +02:00
parent 46d3d2e053
commit e0dcaa0551
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 58 additions and 62 deletions

BIN
wallet/RS

Binary file not shown.

View File

@ -17,16 +17,8 @@ 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 // For internal storage
// No seqno: we can't regenerate the hash of a stored message. multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
// 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).
//
// 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
@ -34,7 +26,7 @@ storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) = StoredMes
// Min 3 signatures per message // Min 3 signatures per message
// ^StoredMessage because 256*(40+) > 1023 // ^StoredMessage because 256*(40+) > 1023
// //
storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(StoredMessage X)) storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(MultiSigWrapperStorage X))
{k:(## 4)} { k > 0 } { k >= 3 } { n >= k } { n <= 10 } = Storage X; {k:(## 4)} { k > 0 } { k >= 3 } { n >= k } { n <= 10 } = Storage X;
// TON stuff // TON stuff

View File

@ -2,19 +2,26 @@
;; Cleanup expired partial orders ;; Cleanup expired partial orders
;; messages ;; messages
(cell) collect_garbage(cell messages) { (cell, ()) ~collect_garbage(cell messages) {
var hash = -1; var hash = -1;
do { do {
(hash, var cs, var ok) = messages.udict_get_next?(256, hash); (hash, var cs, var ok) = messages.udict_get_next?(256, hash);
if (ok) { if (ok) {
;; modeMessage$_ mode:uint8 body:^(Message X) = ModeMessage X;
;; wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X;
;; multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
;;
;; Skip signatures, check expiry
;;
;; expiry <= now ;; expiry <= now
if (cs~load_uint(32) <= now()) { if (cs.skip_dict().preload_uint(32) <= now()) {
messages~udict_delete?(256, hash); messages~udict_delete?(256, hash);
} }
} }
} until (~ ok); } until (~ ok);
return messages; return (messages, ());
} }
() store_db(int seqno, cell keys, cell messages) { () store_db(int seqno, cell keys, cell messages) {
@ -62,16 +69,10 @@
;; 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; ;; multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
;;
;; Skip expiry
;;
;; 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,
;; since all integrity checks were already made when the message was first stored).
;; ;;
;; Load signatures ;; Load signatures
var storedMessageSignatures = storedMessage~load_ref().begin_parse().skip_bits(32).preload_dict(); var storedMessageSignatures = storedMessage~load_ref().begin_parse().preload_dict();
storedMessage.end_parse(); storedMessage.end_parse();
} }
@ -117,16 +118,14 @@
} }
} until (~ ok); } until (~ ok);
;; storedMessage$_ expires_at:uint32 signatures:(HashmapE 4 ^Signature) = StoredMessage X; ;; modeMessage$_ mode:uint8 body:^(Message X) = ModeMessage X;
;; ;; wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X;
;; But do we __have to__ store the body? ;; multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
;; 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)
;; ;;
if (count < min_sigs) { if (count < min_sigs) {
messages~udict_set_ref(256, hash, begin_cell().store_uint(expires_at, 32).store_dict(storedMessageSignatures).end_cell()); messages~udict_set_ref(256, hash, begin_cell().store_dict(storedMessageSignatures).store_uint(expires_at, 32).store_uint(msg_seqno, 32).store_uint(mode, 8).store_ref(message).end_cell());
} }
messages = collect_garbage(messages); messages~collect_garbage();
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(Message X)) = Storage X; ;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(Message X)) = Storage X;
set_data(begin_cell().store_uint(stored_seqno + 1, 32).store_uint(min_sigs, 4).store_dict(keys).store_dict(messages).end_cell()); set_data(begin_cell().store_uint(stored_seqno + 1, 32).store_uint(min_sigs, 4).store_dict(keys).store_dict(messages).end_cell());

View File

@ -1,12 +1,12 @@
"Asm.fif" include "Asm.fif" include
// automatically generated from `/home/daniil/repos/contest/lib/crypto/smartcont/stdlib.fc` `wallet-code.fc` // automatically generated from `/home/daniil/repos/contest/lib/crypto/smartcont/stdlib.fc` `wallet-code.fc`
PROGRAM{ PROGRAM{
DECLPROC collect_garbage DECLPROC ~collect_garbage
DECLPROC store_db DECLPROC store_db
DECLPROC recv_internal DECLPROC recv_internal
DECLPROC recv_external DECLPROC recv_external
85143 DECLMETHOD seqno 85143 DECLMETHOD seqno
collect_garbage PROC:<{ ~collect_garbage PROC:<{
-1 PUSHINT -1 PUSHINT
UNTIL:<{ UNTIL:<{
OVER OVER
@ -17,8 +17,8 @@ PROGRAM{
DUP DUP
IF:<{ IF:<{
s0 s2 XCHG s0 s2 XCHG
32 LDU SKIPDICT
DROP 32 PLDU
NOW NOW
LEQ LEQ
IF:<{ IF:<{
@ -75,15 +75,14 @@ PROGRAM{
LDDICT LDDICT
LDDICT LDDICT
ENDS ENDS
s3 PUSH
NEWDICT NEWDICT
s0 s7 XCHG s4 s6 PUSH2
EQUAL EQUAL
IF:<{ IF:<{
s0 s3 XCHG s0 s4 XCHG
INC INC
}>ELSE<{ }>ELSE<{
s4 s0 PUSH2 s5 s1 PUSH2
8 PUSHPOW2 8 PUSHPOW2
DICTUGET DICTUGET
NULLSWAPIFNOT NULLSWAPIFNOT
@ -91,20 +90,20 @@ PROGRAM{
LDREF LDREF
NIP NIP
ENDS ENDS
s0 s3 XCHG s0 s4 XCHG
}> }>
ACCEPT ACCEPT
s0 s7 XCHG s0 s8 XCHG
-1 PUSHINT -1 PUSHINT
UNTIL:<{ UNTIL:<{
s9 PUSH s10 PUSH
4 PUSHINT 4 PUSHINT
DICTUGETNEXT DICTUGETNEXT
NULLSWAPIFNOT NULLSWAPIFNOT
NULLSWAPIFNOT NULLSWAPIFNOT
DUP DUP
IF:<{ IF:<{
s1 s4 PUSH2 s1 s5 PUSH2
4 PUSHINT 4 PUSHINT
DICTUGET DICTUGET
NULLSWAPIFNOT NULLSWAPIFNOT
@ -122,30 +121,30 @@ PROGRAM{
ENDS ENDS
s0 s2 XCHG s0 s2 XCHG
ENDS ENDS
s9 s(-1) s4 PUXC2 s10 s(-1) s4 PUXC2
CHKSIGNU CHKSIGNU
37 THROWIFNOT 37 THROWIFNOT
s1 s2 XCHG s1 s2 XCHG
4 PUSHINT 4 PUSHINT
s3 s9 s9 PUXC2 s3 s8 s8 PUXC2
DICTUSETREF DICTUSETREF
}>ELSE<{ }>ELSE<{
s1 s8 s8 XCHG3 s1 s7 s7 XCHG3
DROP DROP
}> }>
s0 s7 XCHG s0 s6 XCHG
NOT NOT
}> }>
DROP DROP
s8 POP s9 POP
s0 s7 XCHG s0 s8 XCHG
8 LDU 8 LDU
LDREF LDREF
ENDS ENDS
0 PUSHINT 0 PUSHINT
-1 PUSHINT -1 PUSHINT
UNTIL:<{ UNTIL:<{
s7 PUSH s6 PUSH
4 PUSHINT 4 PUSHINT
DICTUGETNEXT DICTUGETNEXT
NULLSWAPIFNOT NULLSWAPIFNOT
@ -155,45 +154,51 @@ PROGRAM{
IF:<{ IF:<{
s0 s2 XCHG s0 s2 XCHG
INC INC
s0 s5 PUSH2 s0 s6 PUSH2
GEQ GEQ
IF:<{ IF:<{
NIP NIP
s2 s3 PUSH2 s2 s3 PUSH2
SENDRAWMSG SENDRAWMSG
8 PUSHPOW2 8 PUSHPOW2
s7 s6 s6 PUXC2 s8 s12 s12 PUXC2
DICTUDEL DICTUDEL
DROP DROP
0 PUSHINT 0 PUSHINT
}>ELSE<{ }>ELSE<{
s6 s6 XCHG2 s12 s12 XCHG2
}> }>
}>ELSE<{ }>ELSE<{
s0 s6 s6 XCHG3 s0 s12 s12 XCHG3
}> }>
NOT NOT
s6 s6 s0 XCHG3 s12 s12 s0 XCHG3
}> }>
s1 s3 XCHG DROP
3 BLKDROP s4 PUSH
OVER
LESS LESS
IF:<{ IF:<{
NEWC NEWC
s1 s5 XCHG s1 s5 XCHG
32 STU
s1 s3 XCHG
STDICT STDICT
s1 s7 XCHG
32 STU
s1 s5 XCHG
32 STU
s1 s5 XCHG
8 STU
STREF
ENDC ENDC
s0 s2 XCHG s0 s1 s5 XCHG3
8 PUSHPOW2 8 PUSHPOW2
DICTUSETREF DICTUSETREF
}>ELSE<{ }>ELSE<{
s3 s4 XCHG2 s2 s9 XCHG
3 BLKDROP s3 s7 XCHG
s2 s6 XCHG
6 BLKDROP
}> }>
collect_garbage CALLDICT ~collect_garbage CALLDICT
s0 s2 XCHG s0 s2 XCHG
INC INC
NEWC NEWC