1
0
mirror of https://github.com/danog/toncontest.git synced 2024-11-26 20:15:01 +01:00

try adding support for tuples

This commit is contained in:
Daniil Gentili 2019-10-07 14:24:08 +02:00
parent bc0c6a467e
commit ee6ce55976
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 186 additions and 55 deletions

2
lib

@ -1 +1 @@
Subproject commit 2d3b99c2e79558b6cbd91317e2a5628dba3d78c0
Subproject commit f73b5d2babb4045a0d80ccf510a710657ca255a9

BIN
wallet/RS

Binary file not shown.

View File

@ -1,5 +1,16 @@
;; Multisig wallet smart contract
;; Tuple manipulation primitives for integers
tuple tuple_set(tuple t, int index, int value) asm(t value index) "SETINDEXVARQ";
(tuple, ()) ~tuple_set(tuple t, int index, int value) asm(t value index) "SETINDEXVARQ";
;; Tuple manipulation primitives for cells
tuple tuple_setcell(tuple t, int index, cell value) asm(t value index) "SETINDEXVARQ";
(tuple, ()) ~tuple_setcell(tuple t, int index, cell value) asm(t value index) "SETINDEXVARQ";
int tuple_len(tuple t) asm "TLEN";
;; Cleanup expired partial orders
;; messages
(cell, ()) ~collect_garbage(cell messages) {
@ -24,6 +35,50 @@
return (messages, ());
}
;; messages
(slice, (tuple, tuple)) ~load_keys(slice messages) {
int length = messages~load_uint(4);
int index = 0;
var keys = nil;
var keys_cells = nil;
var keys_cell = messages~load_ref();
keys_cells~tuple_setcell(index / 3, keys_cell);
var keys_slice = keys_cell.begin_parse();
do {
if ((index % 3 == 0)) {
if ((index < 9) & (index > 0)) {
keys_slice.end_parse();
var keys_cell = messages~load_ref();
keys_cells~tuple_setcell(index / 3, keys_cell);
var keys_slice = keys_cell.begin_parse();
} else {
var newkeys_slice = keys_slice.preload_ref().begin_parse();
keys_slice.end_parse();
keys_slice = newkeys_slice;
}
}
int key = keys_slice.preload_uint(256);
keys~tuple_set(index, key);
index += 1;
} until (index == length);
keys_slice.end_parse();
return (messages, (keys, keys_cells));
}
builder store_keys(builder b, int length, var keys) {
b~store_uint(4, length);
length = keys.tuple_len();
int index = 0;
do {
b.store_ref(keys.cell_at(index));
index += 1;
} until (index == length);
return b;
}
() store_db(int seqno, cell keys, cell messages) {
set_data(begin_cell().store_uint(seqno, 32).store_dict(keys).store_dict(messages).end_cell());
}
@ -42,19 +97,19 @@
throw_unless(33, in_msg.preload_uint(1));
var signatures = in_msg~load_dict();
var message_data = in_msg;
slice message_data = in_msg;
;; wrappedMessage$_ expires_at:uint32 seqno:uint32 body:^(Message X) = WrappedMessage X;
var (expires_at, msg_seqno) = (message_data~load_uint(32), message_data~load_uint(32));
(int expires_at, int msg_seqno) = (message_data~load_uint(32), message_data~load_uint(32));
;; Message expired
throw_if(34, expires_at <= now());
;; We will need the hash anyway
var hash = slice_hash(in_msg);
int hash = slice_hash(in_msg);
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(StoredMessage X)) = Storage X;
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());
slice stored_data = get_data().begin_parse();
(int stored_seqno, int min_sigs, (var keys, var kcells), var messages) = (stored_data~load_uint(32), stored_data~load_uint(4), stored_data~load_keys(), stored_data~load_dict());
stored_data.end_parse();
;; This is a new message, so there will be no stored messages
@ -83,18 +138,16 @@
do {
(idx, var signature, var ok) = signatures.udict_get_next?(4, idx);
if (ok) {
var (public_key, kok) = keys.udict_get?(4, idx);
throw_unless(36, kok);
var public_key = keys.int_at(idx);
;;throw_unless(at(at(36, kok);
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();
throw_unless(37, check_signature(hash, slice_copy, key));
throw_unless(37, check_signature(hash, slice_copy, public_key));
storedMessageSignatures~udict_set_ref(4, idx, signature_cell);
}
@ -128,7 +181,7 @@
messages~collect_garbage();
;; 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_keys(keys.tuple_len(), kcells).store_dict(messages).end_cell());
}
;; Get methods

View File

@ -2,6 +2,8 @@
// automatically generated from `/home/daniil/repos/contest/lib/crypto/smartcont/stdlib.fc` `wallet-code.fc`
PROGRAM{
DECLPROC ~collect_garbage
DECLPROC ~load_keys
DECLPROC store_keys
DECLPROC store_db
DECLPROC recv_internal
DECLPROC recv_external
@ -39,6 +41,84 @@ PROGRAM{
}>
DROP
}>
~load_keys PROC:<{
4 LDU
0 PUSHINT
PUSHNULL
PUSHNULL
s0 s3 XCHG
LDREF
s4 s1 XCPU
0 PUSHINT
SETINDEXVARQ
SWAP
CTOS
UNTIL:<{
s3 PUSH
3 PUSHINT
MOD
0 EQINT
IF:<{
s3 PUSH
9 LESSINT
s4 PUSH
0 GTINT
AND
IF:<{
DUP
ENDS
s0 s4 XCHG
LDREF
s4 PUSH
3 PUSHINT
DIV
s3 s2 s(-1) XCPUXC
SETINDEXVARQ
NIP
}>ELSE<{
DUP
PLDREF
CTOS
SWAP
ENDS
s4 s4 XCHG2
}>
}>ELSE<{
s4 s4 XCHG2
}>
s4 PUSH
256 PLDU
s3 s0 s4 XC2PU
SETINDEXVARQ
s0 s3 XCHG
INC
s0 s5 PUSH2
EQUAL
s5 s4 s0 XCHG3
s3 s3 s0 XCHG3
}>
s3 POP
s4 POP
SWAP
ENDS
ROT
}>
store_keys PROC:<{
4 PUSHINT
2SWAP
STUX
OVER
TLEN
s2 POP
0 PUSHINT
UNTIL:<{
INC
s0 s2 PUSH2
EQUAL
}>
DROP
NIP
}>
store_db PROC:<{
NEWC
s1 s3 XCHG
@ -72,17 +152,18 @@ PROGRAM{
CTOS
32 LDU
4 LDU
LDDICT
~load_keys CALLDICT
s0 s2 XCHG
LDDICT
ENDS
NEWDICT
s4 s6 PUSH2
s5 s7 PUSH2
EQUAL
IF:<{
s0 s4 XCHG
s0 s5 XCHG
INC
}>ELSE<{
s5 s1 PUSH2
s6 s1 PUSH2
8 PUSHPOW2
DICTUGET
NULLSWAPIFNOT
@ -90,61 +171,52 @@ PROGRAM{
LDREF
NIP
ENDS
s0 s4 XCHG
s0 s5 XCHG
}>
ACCEPT
s0 s8 XCHG
s0 s9 XCHG
-1 PUSHINT
UNTIL:<{
s10 PUSH
s11 PUSH
4 PUSHINT
DICTUGETNEXT
NULLSWAPIFNOT
NULLSWAPIFNOT
DUP
IF:<{
s1 s5 PUSH2
4 PUSHINT
DICTUGET
NULLSWAPIFNOT
36 THROWIFNOT
LDREF
SWAP
CTOS
256 PLDU
s0 s4 XCHG
s5 s1 PUSH2
INDEXVAR
s0 s3 XCHG
LDREF
DROP
DUP
CTOS
DUP
ENDS
s0 s2 XCHG
ENDS
s10 s(-1) s4 PUXC2
s11 s0 s4 PUXC2
CHKSIGNU
37 THROWIFNOT
s1 s2 XCHG
4 PUSHINT
s3 s8 s8 PUXC2
s3 s9 s9 PUXC2
DICTUSETREF
}>ELSE<{
s1 s7 s7 XCHG3
s1 s8 s8 XCHG3
DROP
}>
s0 s6 XCHG
s0 s7 XCHG
NOT
}>
DROP
s9 POP
s0 s8 XCHG
s10 POP
s0 s9 XCHG
8 LDU
LDREF
ENDS
0 PUSHINT
-1 PUSHINT
UNTIL:<{
s6 PUSH
s7 PUSH
4 PUSHINT
DICTUGETNEXT
NULLSWAPIFNOT
@ -154,58 +226,64 @@ PROGRAM{
IF:<{
s0 s2 XCHG
INC
s0 s6 PUSH2
s0 s7 PUSH2
GEQ
IF:<{
NIP
s2 s3 PUSH2
SENDRAWMSG
8 PUSHPOW2
s8 s12 s12 PUXC2
s9 s13 s13 PUXC2
DICTUDEL
DROP
0 PUSHINT
}>ELSE<{
s12 s12 XCHG2
s13 s13 XCHG2
}>
}>ELSE<{
s0 s12 s12 XCHG3
s0 s13 s13 XCHG3
}>
NOT
s12 s12 s0 XCHG3
s13 s13 s0 XCHG3
}>
DROP
s4 PUSH
s5 PUSH
LESS
IF:<{
NEWC
s1 s5 XCHG
s1 s6 XCHG
STDICT
s1 s7 XCHG
s1 s8 XCHG
32 STU
s1 s5 XCHG
s1 s6 XCHG
32 STU
s1 s5 XCHG
s1 s6 XCHG
8 STU
s1 s2 XCHG
STREF
ENDC
s0 s1 s5 XCHG3
s0 s0 s6 XCHG3
8 PUSHPOW2
DICTUSETREF
}>ELSE<{
s2 s9 XCHG
s3 s7 XCHG
s2 s6 XCHG
s4 s10 XCHG
s3 s8 XCHG
s2 s7 XCHG
s4 s6 XCHG
6 BLKDROP
}>
~collect_garbage CALLDICT
s0 s2 XCHG
s0 s3 XCHG
INC
NEWC
32 STU
s1 s4 XCHG
4 STU
s1 s2 XCHG
STDICT
s0 s3 XCHG
TLEN
s2 s3 XCHG
SWAP
store_keys CALLDICT
STDICT
ENDC
c4 POP