@layerzerolabs/layerzero-v2-ton 3.0.12-ton.0 → 3.0.18-ton.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/package.json +15 -4
- package/src/classes/lz/EpConfig.fc +3 -3
- package/src/classes/lz/Packet.fc +16 -3
- package/src/classes/lz/Path.fc +10 -1
- package/src/classes/msgdata/ChannelNonceInfo.fc +3 -3
- package/src/classes/msgdata/Deploy.fc +15 -3
- package/src/classes/msgdata/LzReceivePrepare.fc +18 -0
- package/src/classes/msgdata/LzSend.fc +1 -1
- package/src/classes/msgdata/OptionsV2.fc +7 -4
- package/src/funC++/abstract/contractMainAbstract.fc +12 -1
- package/src/funC++/abstract/handlerAbstract.fc +10 -2
- package/src/funC++/actions/call.fc +5 -3
- package/src/funC++/actions/dispatch.fc +10 -6
- package/src/funC++/baseInterface.fc +9 -8
- package/src/funC++/classlib.fc +30 -33
- package/src/funC++/constants.fc +2 -2
- package/src/funC++/contractMain.fc +2 -0
- package/src/funC++/dataStructures/AddressList.fc +89 -0
- package/src/funC++/dataStructures/DeterministicInsertionCircularQueue.fc +1 -1
- package/src/funC++/dataStructures/PipelinedOutOfOrder.fc +25 -1
- package/src/funC++/handlerCore.fc +2 -0
- package/src/funC++/stdlib.fc +1 -1
- package/src/funC++/testutils.fc +99 -0
- package/src/funC++/utils.fc +66 -2
- package/src/multisig/bocs/MultiSig.compiled.json +5 -0
- package/src/multisig/bocs/MultiSigOrder.compiled.json +5 -0
- package/tests/baseContractTest.fc +15 -12
- package/build/AllStorages.boc +0 -0
- package/build/AllStorages.compiled.json +0 -1
- package/build/AllStorages.fif +0 -4164
- package/build/AllStorages.test.boc +0 -0
- package/build/AllStorages.test.compiled.json +0 -1
- package/build/AllStorages.test.fif +0 -1831
- package/build/BaseContract.test.boc +0 -0
- package/build/BaseContract.test.compiled.json +0 -1
- package/build/BaseContract.test.fif +0 -3553
- package/build/Channel.boc +0 -0
- package/build/Channel.compiled.json +0 -1
- package/build/Channel.fif +0 -5001
- package/build/Channel.permissions.test.boc +0 -0
- package/build/Channel.permissions.test.compiled.json +0 -1
- package/build/Channel.permissions.test.fif +0 -7569
- package/build/ChannelBurn.test.boc +0 -0
- package/build/ChannelBurn.test.compiled.json +0 -1
- package/build/ChannelBurn.test.fif +0 -7454
- package/build/ChannelCommitPacket.test.boc +0 -0
- package/build/ChannelCommitPacket.test.compiled.json +0 -1
- package/build/ChannelCommitPacket.test.fif +0 -7981
- package/build/ChannelConfig.test.boc +0 -0
- package/build/ChannelConfig.test.compiled.json +0 -1
- package/build/ChannelConfig.test.fif +0 -7442
- package/build/ChannelInitialize.test.boc +0 -0
- package/build/ChannelInitialize.test.compiled.json +0 -1
- package/build/ChannelInitialize.test.fif +0 -7289
- package/build/ChannelMsglibIntegration.test.boc +0 -0
- package/build/ChannelMsglibIntegration.test.compiled.json +0 -1
- package/build/ChannelMsglibIntegration.test.fif +0 -7404
- package/build/ChannelMsglibSendCallback.test.boc +0 -0
- package/build/ChannelMsglibSendCallback.test.compiled.json +0 -1
- package/build/ChannelMsglibSendCallback.test.fif +0 -7711
- package/build/ChannelNilify.test.boc +0 -0
- package/build/ChannelNilify.test.compiled.json +0 -1
- package/build/ChannelNilify.test.fif +0 -7672
- package/build/ChannelReceive.test.boc +0 -0
- package/build/ChannelReceive.test.compiled.json +0 -1
- package/build/ChannelReceive.test.fif +0 -7702
- package/build/ChannelReceiveCallback.test.boc +0 -0
- package/build/ChannelReceiveCallback.test.compiled.json +0 -1
- package/build/ChannelReceiveCallback.test.fif +0 -7549
- package/build/ChannelReceiveView.test.boc +0 -0
- package/build/ChannelReceiveView.test.compiled.json +0 -1
- package/build/ChannelReceiveView.test.fif +0 -7352
- package/build/ChannelSend.test.boc +0 -0
- package/build/ChannelSend.test.compiled.json +0 -1
- package/build/ChannelSend.test.fif +0 -7658
- package/build/Classlib.test.boc +0 -0
- package/build/Classlib.test.compiled.json +0 -1
- package/build/Classlib.test.fif +0 -4728
- package/build/Connection.boc +0 -0
- package/build/Connection.compiled.json +0 -1
- package/build/Connection.fif +0 -3503
- package/build/Connection.test.boc +0 -0
- package/build/Connection.test.compiled.json +0 -1
- package/build/Connection.test.fif +0 -6575
- package/build/Controller.assertions.test.boc +0 -0
- package/build/Controller.assertions.test.compiled.json +0 -1
- package/build/Controller.assertions.test.fif +0 -6130
- package/build/Controller.boc +0 -0
- package/build/Controller.compiled.json +0 -1
- package/build/Controller.fif +0 -3195
- package/build/Controller.permissions.test.boc +0 -0
- package/build/Controller.permissions.test.compiled.json +0 -1
- package/build/Controller.permissions.test.fif +0 -6237
- package/build/Controller.test.boc +0 -0
- package/build/Controller.test.compiled.json +0 -1
- package/build/Controller.test.fif +0 -6400
- package/build/Counter.boc +0 -0
- package/build/Counter.compiled.json +0 -1
- package/build/Counter.fif +0 -4809
- package/build/Counter.permissions.test.boc +0 -0
- package/build/Counter.permissions.test.compiled.json +0 -1
- package/build/Counter.permissions.test.fif +0 -7106
- package/build/Counter.setters.test.boc +0 -0
- package/build/Counter.setters.test.compiled.json +0 -1
- package/build/Counter.setters.test.fif +0 -7083
- package/build/Counter.test.boc +0 -0
- package/build/Counter.test.compiled.json +0 -1
- package/build/Counter.test.fif +0 -7540
- package/build/Dvn.boc +0 -0
- package/build/Dvn.compiled.json +0 -1
- package/build/Dvn.fif +0 -2923
- package/build/Dvn.test.boc +0 -0
- package/build/Dvn.test.compiled.json +0 -1
- package/build/Dvn.test.fif +0 -5753
- package/build/Endpoint.boc +0 -0
- package/build/Endpoint.compiled.json +0 -1
- package/build/Endpoint.fif +0 -3694
- package/build/Endpoint.permissions.test.boc +0 -0
- package/build/Endpoint.permissions.test.compiled.json +0 -1
- package/build/Endpoint.permissions.test.fif +0 -6211
- package/build/Endpoint.test.boc +0 -0
- package/build/Endpoint.test.compiled.json +0 -1
- package/build/Endpoint.test.fif +0 -6899
- package/build/EndpointSetEpConfigDefaults.test.boc +0 -0
- package/build/EndpointSetEpConfigDefaults.test.compiled.json +0 -1
- package/build/EndpointSetEpConfigDefaults.test.fif +0 -6529
- package/build/Executor.boc +0 -0
- package/build/Executor.compiled.json +0 -1
- package/build/Executor.fif +0 -2731
- package/build/Executor.test.boc +0 -0
- package/build/Executor.test.compiled.json +0 -1
- package/build/Executor.test.fif +0 -5822
- package/build/LzClasses.test.boc +0 -0
- package/build/LzClasses.test.compiled.json +0 -1
- package/build/LzClasses.test.fif +0 -4457
- package/build/LzUtil.test.boc +0 -0
- package/build/LzUtil.test.compiled.json +0 -1
- package/build/LzUtil.test.fif +0 -1831
- package/build/MsgData.test.boc +0 -0
- package/build/MsgData.test.compiled.json +0 -1
- package/build/MsgData.test.fif +0 -4318
- package/build/MsglibPacketCodec.test.boc +0 -0
- package/build/MsglibPacketCodec.test.compiled.json +0 -1
- package/build/MsglibPacketCodec.test.fif +0 -4851
- package/build/MultiSig.boc +0 -0
- package/build/MultiSig.compiled.json +0 -1
- package/build/MultiSig.fif +0 -727
- package/build/MultiSigOrder.boc +0 -0
- package/build/MultiSigOrder.compiled.json +0 -1
- package/build/MultiSigOrder.fif +0 -650
- package/build/PipelinedOutOfOrder.test.boc +0 -0
- package/build/PipelinedOutOfOrder.test.compiled.json +0 -1
- package/build/PipelinedOutOfOrder.test.fif +0 -2188
- package/build/SmlConnection.boc +0 -0
- package/build/SmlConnection.compiled.json +0 -1
- package/build/SmlConnection.fif +0 -2517
- package/build/SmlConnection.permissions.test.boc +0 -0
- package/build/SmlConnection.permissions.test.compiled.json +0 -1
- package/build/SmlConnection.permissions.test.fif +0 -5497
- package/build/SmlConnection.test.boc +0 -0
- package/build/SmlConnection.test.compiled.json +0 -1
- package/build/SmlConnection.test.fif +0 -5494
- package/build/SmlManager.boc +0 -0
- package/build/SmlManager.compiled.json +0 -1
- package/build/SmlManager.fif +0 -3904
- package/build/SmlManager.permissions.test.boc +0 -0
- package/build/SmlManager.permissions.test.compiled.json +0 -1
- package/build/SmlManager.permissions.test.fif +0 -6018
- package/build/SmlManager.test.boc +0 -0
- package/build/SmlManager.test.compiled.json +0 -1
- package/build/SmlManager.test.fif +0 -6047
- package/build/Uln.boc +0 -0
- package/build/Uln.compiled.json +0 -1
- package/build/Uln.fif +0 -4841
- package/build/Uln.test.boc +0 -0
- package/build/Uln.test.compiled.json +0 -1
- package/build/Uln.test.fif +0 -7077
- package/build/UlnManager.boc +0 -0
- package/build/UlnManager.compiled.json +0 -1
- package/build/UlnManager.fif +0 -3851
- package/build/UlnManager.test.boc +0 -0
- package/build/UlnManager.test.compiled.json +0 -1
- package/build/UlnManager.test.fif +0 -6571
- package/build/UlnReceiveConfig.test.boc +0 -0
- package/build/UlnReceiveConfig.test.compiled.json +0 -1
- package/build/UlnReceiveConfig.test.fif +0 -4413
- package/build/UlnSend.test.boc +0 -0
- package/build/UlnSend.test.compiled.json +0 -1
- package/build/UlnSend.test.fif +0 -6576
- package/build/UlnSendConfig.test.boc +0 -0
- package/build/UlnSendConfig.test.compiled.json +0 -1
- package/build/UlnSendConfig.test.fif +0 -4431
- package/build/UlnSendWorkerFactory.test.boc +0 -0
- package/build/UlnSendWorkerFactory.test.compiled.json +0 -1
- package/build/UlnSendWorkerFactory.test.fif +0 -6683
- package/build/UlnUtil.test.boc +0 -0
- package/build/UlnUtil.test.compiled.json +0 -1
- package/build/UlnUtil.test.fif +0 -5873
- package/build/WorkerCore.test.boc +0 -0
- package/build/WorkerCore.test.compiled.json +0 -1
- package/build/WorkerCore.test.fif +0 -5630
- package/build/ZroMinter.boc +0 -0
- package/build/ZroMinter.compiled.json +0 -1
- package/build/ZroMinter.fif +0 -2300
- package/build/ZroWallet.boc +0 -0
- package/build/ZroWallet.compiled.json +0 -1
- package/build/ZroWallet.fif +0 -2471
- package/src/classes/lz/Attestation.fc +0 -23
- package/src/classes/msgdata/ClaimUnaccountedPoolFunds.fc +0 -0
- package/src/classes/msgdata/InitUlnConnection.fc +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @layerzerolabs/layerzero-v2-ton
|
|
2
2
|
|
|
3
|
+
## 3.0.18-ton.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- uln302
|
|
8
|
+
|
|
9
|
+
## 3.0.14-ton.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- fix ton images
|
|
14
|
+
|
|
15
|
+
## 3.0.13-ton.0
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- loopback wire
|
|
20
|
+
|
|
3
21
|
## 3.0.12-ton.0
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/layerzero-v2-ton",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.18-ton.0",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"import": "./dist/index.mjs",
|
|
8
8
|
"require": "./dist/index.cjs"
|
|
9
9
|
},
|
|
10
|
+
"./build/*.json": {
|
|
11
|
+
"default": "./build/*.json",
|
|
12
|
+
"import": "./build/*.json",
|
|
13
|
+
"require": "./build/*.json"
|
|
14
|
+
},
|
|
15
|
+
"./src/multisig/bocs/*.json": {
|
|
16
|
+
"default": "./src/multisig/bocs/*.json",
|
|
17
|
+
"import": "./src/multisig/bocs/*.json",
|
|
18
|
+
"require": "./src/multisig/bocs/*.json"
|
|
19
|
+
},
|
|
10
20
|
"./package.json": "./package.json"
|
|
11
21
|
},
|
|
12
22
|
"main": "./dist/index.cjs",
|
|
@@ -22,11 +32,12 @@
|
|
|
22
32
|
"src/protocol/",
|
|
23
33
|
"src/jettons/zro/*.fc",
|
|
24
34
|
"tests/testMain.fc",
|
|
25
|
-
"tests/baseContractTest.fc"
|
|
35
|
+
"tests/baseContractTest.fc",
|
|
36
|
+
"src/multisig/bocs/MultiSig.compiled.json",
|
|
37
|
+
"src/multisig/bocs/MultiSigOrder.compiled.json"
|
|
26
38
|
],
|
|
27
39
|
"scripts": {
|
|
28
|
-
"build": "$npm_execpath clean-prebuild && $npm_execpath build
|
|
29
|
-
"build-all": "$npm_execpath blueprint build --all",
|
|
40
|
+
"build": "$npm_execpath clean-prebuild && $npm_execpath blueprint build --all",
|
|
30
41
|
"build-single": "$npm_execpath blueprint build",
|
|
31
42
|
"clean": "$npm_execpath clean-prebuild && rimraf .turbo",
|
|
32
43
|
"clean-prebuild": "rimraf build",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#include "../../funC++/classlib.fc";
|
|
2
2
|
|
|
3
3
|
;; ERRORS
|
|
4
|
-
const int lz::EpConfig::ERROR::sameMsglib =
|
|
5
|
-
const int lz::EpConfig::ERROR::invalidTimeoutExpiry =
|
|
6
|
-
const int lz::EpConfig::ERROR::invalidTimeoutReceiveMsglib =
|
|
4
|
+
const int lz::EpConfig::ERROR::sameMsglib = 1025;
|
|
5
|
+
const int lz::EpConfig::ERROR::invalidTimeoutExpiry = 1026;
|
|
6
|
+
const int lz::EpConfig::ERROR::invalidTimeoutReceiveMsglib = 1027;
|
|
7
7
|
const int lz::EpConfig::VALID = 42069 & ERRORCODE_MASK;
|
|
8
8
|
|
|
9
9
|
;; required storage name
|
package/src/classes/lz/Packet.fc
CHANGED
|
@@ -12,9 +12,9 @@ const int lz::Packet::message = 1;
|
|
|
12
12
|
const int lz::Packet::nonce = 2;
|
|
13
13
|
const int lz::Packet::guid = 3;
|
|
14
14
|
|
|
15
|
-
const int lz::Packet::ERROR::INVALID_MESSAGE =
|
|
16
|
-
const int lz::Packet::ERROR::INVALID_NONCE =
|
|
17
|
-
const int lz::Packet::ERROR::INVALID_PACKET_FIELD =
|
|
15
|
+
const int lz::Packet::ERROR::INVALID_MESSAGE = 1089;
|
|
16
|
+
const int lz::Packet::ERROR::INVALID_NONCE = 1090;
|
|
17
|
+
const int lz::Packet::ERROR::INVALID_PACKET_FIELD = 1091;
|
|
18
18
|
|
|
19
19
|
const int lz::Packet::MAX_RECEIVE_MESSAGE_CELLS = 32;
|
|
20
20
|
const int lz::Packet::MAX_SEND_MESSAGE_CELLS = 255;
|
|
@@ -35,6 +35,19 @@ cell lz::Packet::nonceless(cell $path, cell message) inline method_id {
|
|
|
35
35
|
return lz::Packet::New($path, message, 0);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
;; assumes that the message is a valid single-linked list
|
|
39
|
+
int lz::Packet::_messageBytes(cell $self) impure inline {
|
|
40
|
+
slice messageSlice = $self.cl::get<cellRef>(lz::Packet::message).begin_parse();
|
|
41
|
+
(int sliceBits, int sliceRefs) = messageSlice.slice_bits_refs();
|
|
42
|
+
int messageBytes = sliceBits / 8;
|
|
43
|
+
while (sliceRefs > 0) {
|
|
44
|
+
messageSlice = messageSlice.preload_first_ref().begin_parse();
|
|
45
|
+
(sliceBits, sliceRefs) = messageSlice.slice_bits_refs();
|
|
46
|
+
messageBytes += (sliceBits / 8);
|
|
47
|
+
}
|
|
48
|
+
return messageBytes;
|
|
49
|
+
}
|
|
50
|
+
|
|
38
51
|
() lz::Packet::_assertValidLinkedList(cell head, int maxLen) impure inline {
|
|
39
52
|
slice messageSlice = head.begin_parse();
|
|
40
53
|
repeat (maxLen) {
|
package/src/classes/lz/Path.fc
CHANGED
|
@@ -46,7 +46,7 @@ const int lz::Path::_dstEidOffset = lz::Path::_srcOAppOffset + 256;
|
|
|
46
46
|
;; low-level optimized version
|
|
47
47
|
;; original: 12k gas
|
|
48
48
|
;; optimized: 1k gas
|
|
49
|
-
cell lz::Path::optimizedReverse(cell $path) inline {
|
|
49
|
+
cell lz::Path::optimizedReverse(cell $path) impure inline {
|
|
50
50
|
slice pathSlice = $path.begin_parse();
|
|
51
51
|
return begin_cell()
|
|
52
52
|
.store_slice(pathSlice.scutfirst(_HEADER_WIDTH, 0))
|
|
@@ -54,3 +54,12 @@ cell lz::Path::optimizedReverse(cell $path) inline {
|
|
|
54
54
|
.store_slice(pathSlice.preload_bits_offset(lz::Path::_srcEidOffset, 288)) ;; eid + address
|
|
55
55
|
.end_cell();
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
cell lz::Path::sanitize(cell $path) impure {
|
|
59
|
+
return lz::Path::New(
|
|
60
|
+
$path.cl::get<uint32>(lz::Path::srcEid),
|
|
61
|
+
$path.cl::get<address>(lz::Path::srcOApp),
|
|
62
|
+
$path.cl::get<uint32>(lz::Path::dstEid),
|
|
63
|
+
$path.cl::get<address>(lz::Path::dstOApp)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
const int md::ChannelNonceInfo::NAME = "cNonceInfo"u;
|
|
5
5
|
|
|
6
6
|
;; field names
|
|
7
|
-
const int md::ChannelNonceInfo::
|
|
7
|
+
const int md::ChannelNonceInfo::nonce = 0;
|
|
8
8
|
const int md::ChannelNonceInfo::firstUnexecutedNonce = 1;
|
|
9
9
|
|
|
10
|
-
cell md::ChannelNonceInfo::New(int
|
|
10
|
+
cell md::ChannelNonceInfo::New(int nonce, int firstUnexecutedNonce) inline method_id {
|
|
11
11
|
return cl::declare(
|
|
12
12
|
md::ChannelNonceInfo::NAME,
|
|
13
13
|
unsafeTuple([
|
|
14
|
-
[cl::t::uint64,
|
|
14
|
+
[cl::t::uint64, nonce], ;; md::ChannelNonceInfo::nonce
|
|
15
15
|
[cl::t::uint64, firstUnexecutedNonce] ;; md::ChannelNonceInfo::firstUnexecutedNonce
|
|
16
16
|
])
|
|
17
17
|
);
|
|
@@ -7,14 +7,26 @@ const int md::Deploy::NAME = "deploy"u;
|
|
|
7
7
|
const int md::Deploy::initialDeposit = 0;
|
|
8
8
|
const int md::Deploy::dstEid = 1;
|
|
9
9
|
const int md::Deploy::dstOApp = 2;
|
|
10
|
+
const int md::Deploy::extraInfo = 3;
|
|
10
11
|
|
|
11
12
|
cell md::Deploy::New(int initialDeposit, int dstEid, int dstOApp) inline method_id {
|
|
12
13
|
return cl::declare(
|
|
13
14
|
md::Deploy::NAME,
|
|
14
15
|
unsafeTuple([
|
|
15
|
-
[cl::t::coins, initialDeposit],
|
|
16
|
-
[cl::t::uint32, dstEid],
|
|
17
|
-
[cl::t::uint256, dstOApp]
|
|
16
|
+
[cl::t::coins, initialDeposit], ;; md::Deploy::initialDeposit
|
|
17
|
+
[cl::t::uint32, dstEid], ;; md::Deploy::dstEid
|
|
18
|
+
[cl::t::uint256, dstOApp], ;; md::Deploy::dstOApp
|
|
19
|
+
[cl::t::objRef, cl::nullObject()] ;; md::Deploy::extraInfo
|
|
18
20
|
])
|
|
19
21
|
);
|
|
20
22
|
}
|
|
23
|
+
|
|
24
|
+
cell md::Deploy::NewWithExtraInfo(
|
|
25
|
+
int initialDeposit,
|
|
26
|
+
int dstEid,
|
|
27
|
+
int dstOApp,
|
|
28
|
+
cell $extraInfo
|
|
29
|
+
) method_id {
|
|
30
|
+
return md::Deploy::New(initialDeposit, dstEid, dstOApp)
|
|
31
|
+
.cl::set(md::Deploy::extraInfo, $extraInfo);
|
|
32
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#include "../../funC++/classlib.fc";
|
|
2
|
+
|
|
3
|
+
;; required storage name
|
|
4
|
+
const int md::LzReceivePrepare::NAME = "lzrecvprep"u;
|
|
5
|
+
|
|
6
|
+
;; field names
|
|
7
|
+
const int md::LzReceivePrepare::nonce = 0;
|
|
8
|
+
const int md::LzReceivePrepare::nanotons = 1;
|
|
9
|
+
|
|
10
|
+
cell md::LzReceivePrepare::New(int nonce, int nanotons) method_id {
|
|
11
|
+
return cl::declare(
|
|
12
|
+
md::LzReceivePrepare::NAME,
|
|
13
|
+
unsafeTuple([
|
|
14
|
+
[cl::t::uint64, nonce], ;; md::LzReceivePrepare::nonce
|
|
15
|
+
[cl::t::coins, nanotons] ;; md::LzReceivePrepare::nanotons
|
|
16
|
+
])
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -46,7 +46,7 @@ cell md::lzSend::fillRequestInfo(
|
|
|
46
46
|
int requestId,
|
|
47
47
|
int sendMsglib,
|
|
48
48
|
int sendMsglibConnection
|
|
49
|
-
) inline {
|
|
49
|
+
) inline method_id {
|
|
50
50
|
slice lzSendSlice = $lzSend.begin_parse();
|
|
51
51
|
return begin_cell()
|
|
52
52
|
.store_slice(lzSendSlice.scutfirst(_HEADER_WIDTH, 0))
|
|
@@ -7,8 +7,9 @@ const int md::OptionsV2::NAME = "OptionsV2"u;
|
|
|
7
7
|
const int md::OptionsV2::lzReceiveGas = 0;
|
|
8
8
|
const int md::OptionsV2::lzReceiveValue = 1;
|
|
9
9
|
const int md::OptionsV2::lzComposeGas = 2;
|
|
10
|
-
const int md::OptionsV2::
|
|
11
|
-
const int md::OptionsV2::
|
|
10
|
+
const int md::OptionsV2::lzComposeValue = 3;
|
|
11
|
+
const int md::OptionsV2::nativeDropAddress = 4;
|
|
12
|
+
const int md::OptionsV2::nativeDropAmount = 5;
|
|
12
13
|
|
|
13
14
|
;; This is used to demonstrate that we are capable of having different options objects
|
|
14
15
|
;; This is not finalized and the 'V2' shouldnt be considered a 'valid' options type in the protocol YET
|
|
@@ -18,16 +19,18 @@ cell md::OptionsV2::New(
|
|
|
18
19
|
int lzReceiveGas,
|
|
19
20
|
int lzReceiveValue,
|
|
20
21
|
int lzComposeGas,
|
|
22
|
+
int lzComposeValue,
|
|
21
23
|
int nativeDropAddress,
|
|
22
24
|
int nativeDropAmount
|
|
23
|
-
) inline
|
|
25
|
+
) inline {
|
|
24
26
|
return cl::declare(
|
|
25
27
|
md::OptionsV2::NAME,
|
|
26
28
|
unsafeTuple([
|
|
27
29
|
[cl::t::uint256, lzReceiveGas], ;; md::OptionsV2::lzReceiveGas
|
|
28
30
|
[cl::t::uint256, lzReceiveValue], ;; md::OptionsV2::lzReceiveValue
|
|
29
31
|
[cl::t::uint256, lzComposeGas], ;; md::OptionsV2::lzComposeGas
|
|
30
|
-
[cl::t::
|
|
32
|
+
[cl::t::uint256, lzComposeValue], ;; md::OptionsV2::lzComposeValue
|
|
33
|
+
[cl::t::address, nativeDropAddress], ;; md::OptionsV2::nativeDropAddress
|
|
31
34
|
[cl::t::uint256, nativeDropAmount] ;; md::OptionsV2::nativeDropAmount
|
|
32
35
|
])
|
|
33
36
|
);
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
;;
|
|
1
|
+
;; _executeOpcode is executed at the start of contractMain, after checking permissions.
|
|
2
|
+
;; Each contract implements a list of opcodes, which calls a handler as the entry point
|
|
3
|
+
;; of that opcode. The contract must be initialized in order to start executing opcodes.
|
|
4
|
+
;; @in the opcode to execute
|
|
5
|
+
;; @in the message data extracted from txnContext
|
|
6
|
+
;; @out tuple of resultant actions
|
|
2
7
|
tuple _executeOpcode(int op, cell $md) impure inline;
|
|
8
|
+
|
|
9
|
+
;; Actions are executed after the opcode is executed. Each opcode must emit a tuple
|
|
10
|
+
;; of actions, where each action is executed after the opcode is executed in order.
|
|
11
|
+
;; @in the action to execute
|
|
12
|
+
;; @in the value of the action
|
|
13
|
+
;; @out a bool that determines if excess balance is to be sent back to the origin.
|
|
3
14
|
int _executeAction(int actionType, tuple action) impure inline;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
;;
|
|
1
|
+
;; Assert that the owner has sent an INITIALIZE opcode to this contract
|
|
2
2
|
() assertInitialized() impure inline;
|
|
3
3
|
|
|
4
|
+
;; Assert the identity of the caller for a given opcode
|
|
4
5
|
() checkPermissions(int op, cell $md) impure inline;
|
|
5
6
|
|
|
7
|
+
;; Initialize this contract
|
|
6
8
|
tuple initialize(cell $md) impure inline;
|
|
7
9
|
|
|
10
|
+
;; Authentication = the owner has deployed and sent at least one transaction to this contract
|
|
11
|
+
;; unauthenticated contracts cannot perform any actions.
|
|
12
|
+
;; Authentication enables sharded contracts to trust the identity and intention of other shards
|
|
8
13
|
() authenticateIfNecessary() impure inline;
|
|
9
14
|
|
|
15
|
+
;; Assert the caller is the owner of this contract
|
|
10
16
|
() assertOwner() impure inline;
|
|
11
|
-
() _checkPermissions(int op, cell $md) impure inline;
|
|
12
17
|
|
|
18
|
+
;; Asserts permissions of caller for permissioned opcodes before executing opcode
|
|
19
|
+
;; @see contractMainAbstract.fc
|
|
20
|
+
() _checkPermissions(int op, cell $md) impure inline;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
#include "utils.fc";
|
|
2
|
-
#include "../stdlib.fc";
|
|
3
|
-
#include "../stringlib.fc";
|
|
4
2
|
|
|
5
3
|
const int action::call::NAME = "actionCall"u;
|
|
6
4
|
|
|
@@ -16,8 +14,12 @@ tuple action::call::New(int to, int opcode, cell $md) inline {
|
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
;; returns true if equals
|
|
19
|
-
int action::call::equals(tuple self, tuple other) {
|
|
17
|
+
int action::call::equals(tuple self, tuple other) inline {
|
|
20
18
|
int equalMdField = compareObjectFields(self.cell_at(action::call::md), other.cell_at(action::call::md));
|
|
19
|
+
if (equalMdField != -1) {
|
|
20
|
+
~strdump("call: not equal md field at idx ");
|
|
21
|
+
~dump(equalMdField);
|
|
22
|
+
}
|
|
21
23
|
return (
|
|
22
24
|
(self.int_at(0) == other.int_at(0)) ;; NAME
|
|
23
25
|
& (self.int_at(action::call::to) == other.int_at(action::call::to))
|
|
@@ -42,15 +42,19 @@ tuple _newAction<dispatch>(int to, int opcode, cell $body, int gasNanos) inline
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
int executeDispatch(tuple dispatchAction) {
|
|
45
|
+
cell body = buildLayerzeroMessageBody(
|
|
46
|
+
0,
|
|
47
|
+
dispatchAction.int_at(action::call::opcode),
|
|
48
|
+
dispatchAction.cell_at(action::call::md)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
(int cellsCount, int bitsCount, _) = body.compute_data_size(MAX_U16);
|
|
52
|
+
|
|
45
53
|
sendNonTerminalAction(
|
|
46
54
|
SEND_MSG_BOUNCEABLE,
|
|
47
|
-
dispatchAction.int_at(action::dispatch::gasNanos),
|
|
55
|
+
dispatchAction.int_at(action::dispatch::gasNanos) + get_forward_fee(cellsCount, bitsCount, false),
|
|
48
56
|
dispatchAction.int_at(action::call::to),
|
|
49
|
-
|
|
50
|
-
0,
|
|
51
|
-
dispatchAction.int_at(action::call::opcode),
|
|
52
|
-
dispatchAction.cell_at(action::call::md)
|
|
53
|
-
),
|
|
57
|
+
body,
|
|
54
58
|
NORMAL
|
|
55
59
|
);
|
|
56
60
|
return true;
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
const int BaseInterface::event::AUTHENTICATED = "AUTHENTICATED"u;
|
|
4
4
|
const int BaseInterface::event::INITIALIZED = "INITIALIZED"u;
|
|
5
5
|
|
|
6
|
-
const int BaseInterface::ERROR::notAuthenticated =
|
|
7
|
-
const int BaseInterface::ERROR::onlyOwner =
|
|
8
|
-
const int BaseInterface::ERROR::notInitialized =
|
|
9
|
-
const int BaseInterface::ERROR::alreadyInitialized =
|
|
10
|
-
const int BaseInterface::ERROR::invalidOpcode =
|
|
11
|
-
const int BaseInterface::ERROR::eventEmitted =
|
|
12
|
-
const int BaseInterface::ERROR::invalidActionType =
|
|
13
|
-
const int BaseInterface::ERROR::invalidEventSource =
|
|
6
|
+
const int BaseInterface::ERROR::notAuthenticated = 257;
|
|
7
|
+
const int BaseInterface::ERROR::onlyOwner = 258;
|
|
8
|
+
const int BaseInterface::ERROR::notInitialized = 259;
|
|
9
|
+
const int BaseInterface::ERROR::alreadyInitialized = 260;
|
|
10
|
+
const int BaseInterface::ERROR::invalidOpcode = 261;
|
|
11
|
+
const int BaseInterface::ERROR::eventEmitted = 262;
|
|
12
|
+
const int BaseInterface::ERROR::invalidActionType = 263;
|
|
13
|
+
const int BaseInterface::ERROR::invalidEventSource = 264;
|
|
14
14
|
|
|
15
15
|
const int BaseInterface::OP::INITIALIZE = "BaseInterface::OP::INITIALIZE"c;
|
|
16
|
+
const int BaseInterface::OP::EMPTY = 0;
|
|
16
17
|
const int BaseInterface::OP::EVENT = "BaseInterface::OP::EVENT"c;
|
package/src/funC++/classlib.fc
CHANGED
|
@@ -21,7 +21,8 @@ const int DICT256_KEYLEN = 256;
|
|
|
21
21
|
|
|
22
22
|
const int cl::NULL_CLASS_NAME = "NULL"u;
|
|
23
23
|
|
|
24
|
-
const int cl::ERROR::INVALID_CLASS =
|
|
24
|
+
const int cl::ERROR::INVALID_CLASS = 1057;
|
|
25
|
+
const int cl::ERROR::MALFORMED_OBJECT = 1058;
|
|
25
26
|
|
|
26
27
|
const int DEBUG = 0;
|
|
27
28
|
|
|
@@ -66,10 +67,6 @@ int getContractAddress() impure inline {
|
|
|
66
67
|
return my_address().preload_bits_offset(11, 256).preload_uint(256);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
slice cl::objToSlice(cell $obj) inline method_id {
|
|
70
|
-
return $obj.begin_parse();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
70
|
;;; ====================== Class functions ======================
|
|
74
71
|
;; returns type width in bits
|
|
75
72
|
int _getTypeWidth(int clType) inline {
|
|
@@ -171,7 +168,7 @@ int cl::typeof(cell $obj) inline method_id {
|
|
|
171
168
|
return $obj.begin_parse().preload_uint(_NAME_WIDTH);
|
|
172
169
|
}
|
|
173
170
|
|
|
174
|
-
cell cl::declare(int name, tuple fields) inline
|
|
171
|
+
cell cl::declare(int name, tuple fields) inline {
|
|
175
172
|
tuple classBuilder = unsafeTuple([null(), begin_cell()]);
|
|
176
173
|
|
|
177
174
|
if (DEBUG) {
|
|
@@ -207,13 +204,15 @@ cell cl::declare(int name, tuple fields) inline method_id {
|
|
|
207
204
|
classBuilder = classBuilder.tpush(begin_cell());
|
|
208
205
|
}
|
|
209
206
|
}
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
207
|
+
if (fieldBits == 0) {
|
|
208
|
+
if ((curRefOffset + 1) > curCellMaxRefs) {
|
|
209
|
+
;; move to the next cell
|
|
210
|
+
curRefCell += 1;
|
|
211
|
+
curRefOffset = 0;
|
|
212
|
+
curCellMaxRefs = MAX_CELL_REFS;
|
|
213
|
+
if (curRefCell >= classBuilder.tlen()) {
|
|
214
|
+
classBuilder = classBuilder.tpush(begin_cell());
|
|
215
|
+
}
|
|
217
216
|
}
|
|
218
217
|
}
|
|
219
218
|
|
|
@@ -295,35 +294,35 @@ cell cl::nullObject() inline method_id {
|
|
|
295
294
|
}
|
|
296
295
|
|
|
297
296
|
;;; ====================== Class Setter ======================
|
|
298
|
-
int cl::getFieldType::asm(slice self, int fieldInfoOffset
|
|
297
|
+
int cl::getFieldType::asm(slice self, int fieldInfoOffset) asm """
|
|
299
298
|
// STACK [fieldInfoOffset, headerSlice]
|
|
300
299
|
4 PUSHINT // STACK [_FIELD_TYPE_WIDTH, fieldInfoOffset, headerSlice]
|
|
301
300
|
SDSUBSTR // STACK [substring]
|
|
302
301
|
4 PLDU // STACK [2BitUnsignInt]
|
|
303
302
|
""";
|
|
304
303
|
|
|
305
|
-
int cl::getFieldCellIndex::asm(slice self, int fieldInfoOffset
|
|
304
|
+
int cl::getFieldCellIndex::asm(slice self, int fieldInfoOffset) asm """
|
|
306
305
|
4 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
|
|
307
306
|
2 PUSHINT // STACK [_CELL_ID_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
|
|
308
307
|
SDSUBSTR // STACK [substring]
|
|
309
308
|
2 PLDU // STACK [2BitUnsignInt]
|
|
310
309
|
""";
|
|
311
310
|
|
|
312
|
-
int cl::getFieldOffset::asm(slice self, int fieldInfoOffset
|
|
311
|
+
int cl::getFieldOffset::asm(slice self, int fieldInfoOffset) asm """
|
|
313
312
|
6 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
|
|
314
313
|
10 PUSHINT // STACK [_DATA_OFFSET_WIDTH, fieldInfoOffset +_FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
|
|
315
314
|
SDSUBSTR // STACK [substring]
|
|
316
315
|
10 PLDU // STACK [10BitUnsignInt]
|
|
317
316
|
""";
|
|
318
317
|
|
|
319
|
-
int cl::getFieldCellOffset::asm(slice self, int fieldInfoOffset
|
|
318
|
+
int cl::getFieldCellOffset::asm(slice self, int fieldInfoOffset) asm """
|
|
320
319
|
16 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH, headerSlice]
|
|
321
320
|
2 PUSHINT // STACK [_REF_OFFSET_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH headerSlice]
|
|
322
321
|
SDSUBSTR // STACK [substring]
|
|
323
322
|
2 PLDU // STACK [10BitUnsignInt]
|
|
324
323
|
""";
|
|
325
324
|
|
|
326
|
-
int cl::preload_bits_offset_3::asm(int width1, slice self, int fieldOffset, int width2
|
|
325
|
+
int cl::preload_bits_offset_3::asm(int width1, slice self, int fieldOffset, int width2) asm """
|
|
327
326
|
SDSUBSTR // STACK [substring]
|
|
328
327
|
s1 XCHG0
|
|
329
328
|
PLDUX // STACK [10BitUnsignInt] (CC +1 )
|
|
@@ -460,10 +459,6 @@ cell cl::get<cellRef>(cell $self, int fieldName) inline method_id {
|
|
|
460
459
|
);
|
|
461
460
|
}
|
|
462
461
|
|
|
463
|
-
cell cl::getWithCell<cellRef>(cell $self, int fieldName) inline method_id {
|
|
464
|
-
return $self.cl::get<cellRef>(fieldName);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
462
|
cell cl::get<objRef>(cell $self, int fieldName) inline method_id {
|
|
468
463
|
return cl::get<cellRef>($self, fieldName);
|
|
469
464
|
}
|
|
@@ -523,6 +518,7 @@ int typeofField(cell $self, int fieldName) inline {
|
|
|
523
518
|
}
|
|
524
519
|
|
|
525
520
|
;; returns -1 (true) if equal, otherwise the index of the first field that differs
|
|
521
|
+
;; returns 16 if the types of the objects are not equal
|
|
526
522
|
int compareObjectFields(cell $lhs, cell $rhs) impure inline {
|
|
527
523
|
int malformed = cl::typeof($lhs) != cl::typeof($rhs);
|
|
528
524
|
if (malformed) {
|
|
@@ -551,7 +547,8 @@ int compareObjectFields(cell $lhs, cell $rhs) impure inline {
|
|
|
551
547
|
fieldIndex = INVALID_CLASS_MEMBER;
|
|
552
548
|
}
|
|
553
549
|
if (malformed) {
|
|
554
|
-
|
|
550
|
+
~strdump("Malformed field");
|
|
551
|
+
~dump(fieldIndex);
|
|
555
552
|
return fieldIndex;
|
|
556
553
|
}
|
|
557
554
|
fieldIndex += 1;
|
|
@@ -634,17 +631,17 @@ slice _typeToStr(int fieldType) {
|
|
|
634
631
|
|
|
635
632
|
;;; ====================== Dictionary functions ======================
|
|
636
633
|
|
|
637
|
-
slice uint256ToSlice(int val) inline
|
|
634
|
+
slice uint256ToSlice(int val) inline {
|
|
638
635
|
return begin_cell().store_uint256(val).as_slice();
|
|
639
636
|
}
|
|
640
637
|
|
|
641
|
-
int sliceToUint256(slice s) inline
|
|
638
|
+
int sliceToUint256(slice s) inline {
|
|
642
639
|
return s.preload_uint(256);
|
|
643
640
|
}
|
|
644
641
|
|
|
645
642
|
;; override the insane behavior of TON to optimize out empty dictionaries
|
|
646
643
|
;; into a single bit
|
|
647
|
-
cell cl::dict256::New() inline
|
|
644
|
+
cell cl::dict256::New() inline {
|
|
648
645
|
return empty_cell();
|
|
649
646
|
}
|
|
650
647
|
|
|
@@ -767,7 +764,7 @@ cell cl::dict256::delete(cell dict, int key) {
|
|
|
767
764
|
return (-1, null());
|
|
768
765
|
}
|
|
769
766
|
|
|
770
|
-
int cl::dict256::size(cell dict) inline {
|
|
767
|
+
int cl::dict256::size(cell dict) inline method_id {
|
|
771
768
|
int count = 0;
|
|
772
769
|
(int pivot, _) = dict.cl::dict256::getMin<slice>();
|
|
773
770
|
while (pivot >= 0) {
|
|
@@ -779,7 +776,7 @@ int cl::dict256::size(cell dict) inline {
|
|
|
779
776
|
|
|
780
777
|
;;; ====================== Nested Dict Helpers ======================
|
|
781
778
|
|
|
782
|
-
forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X val) inline
|
|
779
|
+
forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X val) inline {
|
|
783
780
|
return $self.cl::set(
|
|
784
781
|
fieldName,
|
|
785
782
|
$self
|
|
@@ -788,29 +785,29 @@ forall X -> cell cl::nestedDict256::set(cell $self, int fieldName, int key, X va
|
|
|
788
785
|
);
|
|
789
786
|
}
|
|
790
787
|
|
|
791
|
-
cell cl::nestedDict256::setRef(cell $self, int fieldName, int key, cell val) inline
|
|
788
|
+
cell cl::nestedDict256::setRef(cell $self, int fieldName, int key, cell val) inline {
|
|
792
789
|
return $self.cl::set(
|
|
793
790
|
fieldName,
|
|
794
791
|
$self.cl::get<dict256>(fieldName).cl::dict256::setRef(key, val)
|
|
795
792
|
);
|
|
796
793
|
}
|
|
797
794
|
|
|
798
|
-
cell cl::nestedDict256::delete(cell $self, int fieldName, int key) inline
|
|
795
|
+
cell cl::nestedDict256::delete(cell $self, int fieldName, int key) inline {
|
|
799
796
|
return $self.cl::set(
|
|
800
797
|
fieldName,
|
|
801
798
|
$self.cl::get<dict256>(fieldName).cl::dict256::delete(key)
|
|
802
799
|
);
|
|
803
800
|
}
|
|
804
801
|
|
|
805
|
-
(int, int) cl::nestedDict256::get<uint256>(cell $self, int fieldName, int key) inline
|
|
802
|
+
(int, int) cl::nestedDict256::get<uint256>(cell $self, int fieldName, int key) inline {
|
|
806
803
|
return $self.cl::get<dict256>(fieldName).cl::dict256::get<uint256>(key);
|
|
807
804
|
}
|
|
808
805
|
|
|
809
|
-
(slice, int) cl::nestedDict256::get<slice>(cell $self, int fieldName, int key) inline
|
|
806
|
+
(slice, int) cl::nestedDict256::get<slice>(cell $self, int fieldName, int key) inline {
|
|
810
807
|
return $self.cl::get<dict256>(fieldName).cl::dict256::get(key);
|
|
811
808
|
}
|
|
812
809
|
|
|
813
|
-
(cell, int) cl::nestedDict256::get<cellRef>(cell $self, int fieldName, int key) inline
|
|
810
|
+
(cell, int) cl::nestedDict256::get<cellRef>(cell $self, int fieldName, int key) inline {
|
|
814
811
|
(slice s, int exists) = $self.cl::get<dict256>(fieldName).cl::dict256::get(key);
|
|
815
812
|
if (exists) {
|
|
816
813
|
return (s.preload_first_ref(), exists);
|
package/src/funC++/constants.fc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const int ERRORCODE_MASK = 0x7ff;
|
|
2
|
-
const int CLASSLIB::ERROR::INVALID_FIELD_TYPE =
|
|
3
|
-
const int CLASSLIB::ERROR::WRONG_ORDER_CONSTRUCTOR =
|
|
2
|
+
const int CLASSLIB::ERROR::INVALID_FIELD_TYPE = 1058;
|
|
3
|
+
const int CLASSLIB::ERROR::WRONG_ORDER_CONSTRUCTOR = 1059;
|
|
4
4
|
|
|
5
5
|
const int MAX_U8 = 0xFF;
|
|
6
6
|
const int MAX_U16 = 0xFFFF;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#include "../utils.fc";
|
|
2
|
+
|
|
3
|
+
const int AddressList::addressBits = 256;
|
|
4
|
+
;; you can create an address list from a tuple of addresses [integers]
|
|
5
|
+
cell AddressList::serialize(tuple addressList) impure inline {
|
|
6
|
+
tuple addressListBuilder = unsafeTuple([begin_cell()]);
|
|
7
|
+
int idx = 0;
|
|
8
|
+
while (idx < addressList.tlen()) {
|
|
9
|
+
builder curBuilder = addressListBuilder.at(addressListBuilder.tlen() - 1);
|
|
10
|
+
if ((curBuilder.builder_bits() + AddressList::addressBits) > MAX_CELL_BITS) {
|
|
11
|
+
addressListBuilder = addressListBuilder.tpush(begin_cell());
|
|
12
|
+
curBuilder = addressListBuilder.at(addressListBuilder.tlen() - 1);
|
|
13
|
+
}
|
|
14
|
+
addressListBuilder = addressListBuilder
|
|
15
|
+
.tset(
|
|
16
|
+
addressListBuilder.tlen() - 1,
|
|
17
|
+
curBuilder.store_uint256(addressList.int_at(idx))
|
|
18
|
+
);
|
|
19
|
+
idx = idx + 1;
|
|
20
|
+
}
|
|
21
|
+
builder ret = addressListBuilder~tpop();
|
|
22
|
+
while (addressListBuilder.tlen() > 0) {
|
|
23
|
+
builder head = addressListBuilder~tpop();
|
|
24
|
+
ret = head.store_ref(ret.end_cell());
|
|
25
|
+
}
|
|
26
|
+
return ret.end_cell();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
;; the "iterator" is the remaining slice
|
|
30
|
+
(slice, int) ~AddressList::next(slice addressListSlice) impure inline {
|
|
31
|
+
if (addressListSlice.slice_bits() == 0) {
|
|
32
|
+
if (addressListSlice.slice_refs_empty?()) {
|
|
33
|
+
return (addressListSlice, NULLADDRESS);
|
|
34
|
+
} else {
|
|
35
|
+
addressListSlice = addressListSlice.preload_first_ref().begin_parse();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return addressListSlice.load_uint256();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
;; Check that the addresslist is a valid linked list of addresses with no extra refs or bytes
|
|
42
|
+
int AddressList::isValid(cell addressList, int maxCount) {
|
|
43
|
+
slice addressListSlice = addressList.begin_parse();
|
|
44
|
+
int count = 0;
|
|
45
|
+
while (addressListSlice.slice_empty?() == false) {
|
|
46
|
+
(int bits, int refs) = addressListSlice.slice_bits_refs();
|
|
47
|
+
if ((refs > 1) | ((refs == 1) & ((bits % 256) != 0))) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
repeat (bits / 256) {
|
|
51
|
+
count += 1;
|
|
52
|
+
int address = addressListSlice~load_uint256();
|
|
53
|
+
if ((address == NULLADDRESS) | (count > maxCount)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (addressListSlice.slice_refs() > 0) {
|
|
58
|
+
addressListSlice = addressListSlice.preload_first_ref().begin_parse();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
int AddressList::includes(int address, slice addressListSlice) impure inline {
|
|
66
|
+
int storedAddress = addressListSlice~AddressList::next();
|
|
67
|
+
while (storedAddress > NULLADDRESS) {
|
|
68
|
+
if (storedAddress == address) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
storedAddress = addressListSlice~AddressList::next();
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int AddressList::length(cell addressList) impure inline {
|
|
77
|
+
slice addressListSlice = addressList.begin_parse();
|
|
78
|
+
int count = 0;
|
|
79
|
+
int dvnAddress = addressListSlice~AddressList::next();
|
|
80
|
+
while (dvnAddress > NULLADDRESS) {
|
|
81
|
+
count += 1;
|
|
82
|
+
dvnAddress = addressListSlice~AddressList::next();
|
|
83
|
+
}
|
|
84
|
+
return count;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
cell AddressList::empty() impure inline {
|
|
88
|
+
return empty_cell();
|
|
89
|
+
}
|