mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add TVM instructions for working with nonzero-level cells (#880)
Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
64b04e46d7
commit
51d30e2f2b
6 changed files with 156 additions and 1 deletions
|
@ -813,6 +813,12 @@ x{D761} @Defop LDONES
|
|||
x{D762} @Defop LDSAME
|
||||
x{D764} @Defop SDEPTH
|
||||
x{D765} @Defop CDEPTH
|
||||
x{D766} @Defop CLEVEL
|
||||
x{D767} @Defop CLEVELMASK
|
||||
{ <b x{D76A_} s, swap 2 u, @addopb } : CHASHI
|
||||
{ <b x{D76E_} s, swap 2 u, @addopb } : CDEPTHI
|
||||
x{D770} @Defop CHASHIX
|
||||
x{D771} @Defop CDEPTHIX
|
||||
//
|
||||
// continuation / flow control primitives
|
||||
x{D8} dup @Defop EXECUTE @Defop CALLX
|
||||
|
|
|
@ -163,3 +163,7 @@ TEST(Fift, test_bls) {
|
|||
TEST(Fift, test_bls_ops) {
|
||||
run_fift("bls_ops.fif");
|
||||
}
|
||||
|
||||
TEST(Fift, test_levels) {
|
||||
run_fift("levels.fif");
|
||||
}
|
||||
|
|
75
crypto/test/fift/levels.fif
Normal file
75
crypto/test/fift/levels.fif
Normal file
|
@ -0,0 +1,75 @@
|
|||
"Asm.fif" include
|
||||
"FiftExt.fif" include
|
||||
|
||||
{
|
||||
dup
|
||||
."Cell " .dump cr
|
||||
dup [[ <{ CLEVEL }>s ]] 0 runvmx abort"exitcode != 0" ."Level = " . cr
|
||||
dup [[ <{ CLEVELMASK }>s ]] 0 runvmx abort"exitcode != 0" ."Level mask = 0b" b. cr
|
||||
dup dup [[ <{ 0 CHASHI DUP ROT 0 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_0 = " X. cr
|
||||
dup dup [[ <{ 1 CHASHI DUP ROT 1 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_1 = " X. cr
|
||||
dup dup [[ <{ 2 CHASHI DUP ROT 2 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_2 = " X. cr
|
||||
dup dup [[ <{ 3 CHASHI DUP ROT 3 INT CHASHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Hash_3 = " X. cr
|
||||
dup dup [[ <{ 0 CDEPTHI DUP ROT 0 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_0 = " . cr
|
||||
dup dup [[ <{ 1 CDEPTHI DUP ROT 1 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_1 = " . cr
|
||||
dup dup [[ <{ 2 CDEPTHI DUP ROT 2 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_2 = " . cr
|
||||
dup dup [[ <{ 3 CDEPTHI DUP ROT 3 INT CDEPTHIX EQUAL 55 THROWIFNOT }>s ]] 0 runvmx abort"exitcode != 0" ."Depth_3 = " . cr
|
||||
drop
|
||||
cr
|
||||
} : print-all
|
||||
|
||||
// Ordinary cell of level 0
|
||||
<b
|
||||
123 32 u,
|
||||
<b <b 22 32 u, b> ref, b> ref,
|
||||
<b b> ref,
|
||||
b>
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 1
|
||||
<b
|
||||
1 8 u,
|
||||
1 8 u,
|
||||
0xabcd1111abcd1111abcd1111abcd1111abcd1111abcd1111abcd1111abcd1111 256 u,
|
||||
14 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 3
|
||||
<b
|
||||
1 8 u,
|
||||
7 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
44 16 u,
|
||||
33 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Prunned branch of level 3, mask 0b101
|
||||
<b
|
||||
1 8 u,
|
||||
5 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
33 16 u,
|
||||
b>spec
|
||||
print-all
|
||||
|
||||
// Tree with the previous cell inside
|
||||
<b
|
||||
<b
|
||||
<b
|
||||
1 8 u,
|
||||
5 8 u,
|
||||
0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 256 u,
|
||||
0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc 256 u,
|
||||
55 16 u,
|
||||
33 16 u,
|
||||
b>spec ref,
|
||||
b> ref,
|
||||
b>
|
||||
print-all
|
|
@ -1391,6 +1391,55 @@ int exec_slice_depth(VmState* st) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_level(VmState* st) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute CLEVEL";
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_level());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_level_mask(VmState* st) {
|
||||
Stack& stack = st->get_stack();
|
||||
VM_LOG(st) << "execute CLEVELMASK";
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_level_mask().get_mask());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_hash_i(VmState* st, unsigned args, bool var) {
|
||||
unsigned i;
|
||||
Stack& stack = st->get_stack();
|
||||
if (var) {
|
||||
VM_LOG(st) << "execute CHASHIX";
|
||||
i = stack.pop_smallint_range(3);
|
||||
} else {
|
||||
i = args & 3;
|
||||
VM_LOG(st) << "execute CHASHI " << i;
|
||||
}
|
||||
auto cell = stack.pop_cell();
|
||||
std::array<unsigned char, 32> hash = cell->get_hash(i).as_array();
|
||||
td::RefInt256 res{true};
|
||||
CHECK(res.write().import_bytes(hash.data(), hash.size(), false));
|
||||
stack.push_int(std::move(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_cell_depth_i(VmState* st, unsigned args, bool var) {
|
||||
unsigned i;
|
||||
Stack& stack = st->get_stack();
|
||||
if (var) {
|
||||
VM_LOG(st) << "execute CDEPTHIX";
|
||||
i = stack.pop_smallint_range(3);
|
||||
} else {
|
||||
i = args & 3;
|
||||
VM_LOG(st) << "execute CDEPTHI " << i;
|
||||
}
|
||||
auto cell = stack.pop_cell();
|
||||
stack.push_smallint(cell->get_depth(i));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void register_cell_deserialize_ops(OpcodeTable& cp0) {
|
||||
using namespace std::placeholders;
|
||||
cp0.insert(OpcodeInstr::mksimple(0xd0, 8, "CTOS", exec_cell_to_slice))
|
||||
|
@ -1479,7 +1528,13 @@ void register_cell_deserialize_ops(OpcodeTable& cp0) {
|
|||
.insert(OpcodeInstr::mksimple(0xd761, 16, "LDONES", std::bind(exec_load_same, _1, "LDONES", 1)))
|
||||
.insert(OpcodeInstr::mksimple(0xd762, 16, "LDSAME", std::bind(exec_load_same, _1, "LDSAME", -1)))
|
||||
.insert(OpcodeInstr::mksimple(0xd764, 16, "SDEPTH", exec_slice_depth))
|
||||
.insert(OpcodeInstr::mksimple(0xd765, 16, "CDEPTH", exec_cell_depth));
|
||||
.insert(OpcodeInstr::mksimple(0xd765, 16, "CDEPTH", exec_cell_depth))
|
||||
.insert(OpcodeInstr::mksimple(0xd766, 16, "CLEVEL", exec_cell_level)->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd767, 16, "CLEVELMASK", exec_cell_level_mask)->require_version(6))
|
||||
.insert(OpcodeInstr::mkfixed(0xd768 >> 2, 14, 2, instr::dump_1c_and(3, "CHASHI "), std::bind(exec_cell_hash_i, _1, _2, false))->require_version(6))
|
||||
.insert(OpcodeInstr::mkfixed(0xd76c >> 2, 14, 2, instr::dump_1c_and(3, "CDEPTHI "), std::bind(exec_cell_depth_i, _1, _2, false))->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd770, 16, "CHASHIX ", std::bind(exec_cell_hash_i, _1, 0, true))->require_version(6))
|
||||
.insert(OpcodeInstr::mksimple(0xd771, 16, "CDEPTHIX ", std::bind(exec_cell_depth_i, _1, 0, true))->require_version(6));
|
||||
}
|
||||
|
||||
void register_cell_ops(OpcodeTable& cp0) {
|
||||
|
|
|
@ -69,12 +69,26 @@ If the parameter is absent from the config, the value is null.
|
|||
* **6**: `ConfigParam 43` (size limits).
|
||||
|
||||
### New TVM instructions
|
||||
|
||||
#### Fee calculation
|
||||
* `GETEXECUTIONPRICE` (`gas_used is_mc - price`) - calculates gas fee.
|
||||
* `GETSTORAGEPRICE` (`cells bits seconds is_mc - price`) - calculates storage fees (only current StoragePrices entry is used).
|
||||
* `GETFORWARDPRICE` (`cells bits is_mc - price`) - calculates forward fee.
|
||||
* `GETPRECOMPILEDGAS` (`- null`) - reserved, currently returns `null`.
|
||||
|
||||
`gas_used`, `cells`, `bits`, `time_delta` are integers in range `0..2^63-1`.
|
||||
|
||||
#### Cell operations
|
||||
Operations for working with Merkle proofs, where cells can have non-zero level and multiple hashes.
|
||||
* `CLEVEL` (`cell - level`) - returns level of the cell.
|
||||
* `CLEVELMASK` (`cell - level_mask`) - returns level mask of the cell.
|
||||
* `i CHASHI` (`cell - hash`) - returns `i`th hash of the cell.
|
||||
* `i CDEPTHI` (`cell - depth`) - returns `i`th depth of the cell.
|
||||
* `CHASHIX` (`cell i - hash`) - returns `i`th hash of the cell.
|
||||
* `CDEPTHIX` (`cell i - depth`) - returns `i`th depth of the cell.
|
||||
|
||||
`i` is in range `0..3`.
|
||||
|
||||
### Other changes
|
||||
* `GLOBALID` gets `ConfigParam 19` from the tuple, not from the config dict. This decreases gas usage.
|
||||
* `SENDMSG` gets `ConfigParam 24/25` (message prices) from the tuple, not from the config dict, and also uses `ConfigParam 43` to get max_msg_cells.
|
|
@ -18,6 +18,7 @@ Test_Fift_test_fiftext_default 2b0db5d4d4bfbc705b959cc787540d7b3a21a71469eac5475
|
|||
Test_Fift_test_fixed_default 278a19d56b773102caf5c1fe2997ea6c8d0d9e720eff8503feede6398a197eec
|
||||
Test_Fift_test_hash_ext_default 686fc5680feca5b3bb207768215b27f6872a95128762dee0d7f2c88bc492d62d
|
||||
Test_Fift_test_hmap_default c269246882039824bb5822e896c3e6e82ef8e1251b6b251f5af8ea9fb8d05067
|
||||
Test_Fift_test_levels_default 9fba4a7c98aec9000f42846d6e5fd820343ba61d68f9139dd16c88ccda757cf3
|
||||
Test_Fift_test_namespaces_default e6419619c51332fb5e8bf22043ef415db686c47fe24f03061e5ad831014e7c6c
|
||||
Test_Fift_test_rist255_default f4d7558f200a656934f986145c19b1dedbe2ad029292a5a975576d6891e25fc4
|
||||
Test_Fift_test_sort2_default 9b57d47e6a10e7d1bbb565db35400debf2f963031f434742a702ec76555a5d3a
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue