@layerzerolabs/layerzero-v2-ton 3.0.18-ton.2 → 3.0.19-ton.1
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 +4 -88
- package/build/AllStorages.compiled.json +1 -1
- package/build/AllStorages.test.compiled.json +1 -1
- package/build/BaseContract.test.compiled.json +1 -1
- package/build/Channel.compiled.json +1 -1
- package/build/Channel.permissions.test.compiled.json +1 -1
- package/build/ChannelBurn.test.compiled.json +1 -1
- package/build/ChannelCommitPacket.test.compiled.json +1 -1
- package/build/ChannelConfig.test.compiled.json +1 -1
- package/build/ChannelInitialize.test.compiled.json +1 -1
- package/build/ChannelMsglibIntegration.test.compiled.json +1 -1
- package/build/ChannelMsglibSendCallback.test.compiled.json +1 -1
- package/build/ChannelNilify.test.compiled.json +1 -1
- package/build/ChannelReceive.test.compiled.json +1 -1
- package/build/ChannelReceiveCallback.test.compiled.json +1 -1
- package/build/ChannelReceiveView.test.compiled.json +1 -1
- package/build/ChannelSend.test.compiled.json +1 -1
- package/build/Classlib.test.compiled.json +1 -1
- package/build/ComputeDataSizeGas.test.compiled.json +1 -1
- package/build/Connection.compiled.json +1 -1
- package/build/Controller.assertions.test.compiled.json +1 -1
- package/build/Controller.compiled.json +1 -1
- package/build/Controller.permissions.test.compiled.json +1 -1
- package/build/Controller.test.compiled.json +1 -1
- package/build/Counter.compiled.json +1 -1
- package/build/Counter.permissions.test.compiled.json +1 -1
- package/build/Counter.setters.test.compiled.json +1 -1
- package/build/Counter.test.compiled.json +1 -1
- package/build/Dvn.compiled.json +1 -1
- package/build/Dvn.test.compiled.json +1 -1
- package/build/DvnFeeLib.compiled.json +1 -1
- package/build/DvnPermissions.test.compiled.json +1 -1
- package/build/Endpoint.compiled.json +1 -1
- package/build/Endpoint.permissions.test.compiled.json +1 -1
- package/build/Endpoint.test.compiled.json +1 -1
- package/build/EndpointSetEpConfigDefaults.test.compiled.json +1 -1
- package/build/Executor.compiled.json +1 -1
- package/build/Executor.test.compiled.json +1 -1
- package/build/ExecutorFeeLib.compiled.json +1 -1
- package/build/ExecutorPermissions.test.compiled.json +1 -1
- package/build/LzClasses.test.compiled.json +1 -1
- package/build/LzUtil.test.compiled.json +1 -1
- package/build/MsgData.test.compiled.json +1 -1
- package/build/MsglibPacketCodec.test.compiled.json +1 -1
- package/build/PipelinedOutOfOrder.test.compiled.json +1 -1
- package/build/PriceFeedCache.compiled.json +1 -1
- package/build/PriceFeedCache.permissions.test.compiled.json +1 -1
- package/build/PriceFeedCache.test.compiled.json +1 -1
- package/build/Proxy.compiled.json +1 -1
- package/build/Proxy.permissions.test.compiled.json +1 -1
- package/build/Proxy.test.compiled.json +1 -1
- package/build/SmlConnection.compiled.json +1 -1
- package/build/SmlConnection.permissions.test.compiled.json +1 -1
- package/build/SmlConnection.test.compiled.json +1 -1
- package/build/SmlManager.compiled.json +1 -1
- package/build/SmlManager.permissions.test.compiled.json +1 -1
- package/build/SmlManager.test.compiled.json +1 -1
- package/build/Uln.compiled.json +1 -1
- package/build/Uln.test.compiled.json +1 -1
- package/build/UlnConnection.compiled.json +1 -1
- package/build/UlnConnection.test.compiled.json +1 -1
- package/build/UlnConnectionPermissions.test.compiled.json +1 -1
- package/build/UlnManagement.test.compiled.json +1 -1
- package/build/UlnManager.compiled.json +1 -1
- package/build/UlnManager.test.compiled.json +1 -1
- package/build/UlnManagerPermissions.test.compiled.json +1 -1
- package/build/UlnManagerUtil.test.compiled.json +1 -1
- package/build/UlnPermissions.test.compiled.json +1 -1
- package/build/UlnReceiveConfig.test.compiled.json +1 -1
- package/build/UlnSend.test.compiled.json +1 -1
- package/build/UlnSendConfig.test.compiled.json +1 -1
- package/build/UlnSendWithDvnFeeLib.test.compiled.json +1 -1
- package/build/UlnSendWithExecFeeLib.test.compiled.json +1 -1
- package/build/UlnSendWorkerFactory.test.compiled.json +1 -1
- package/build/UlnUtil.test.compiled.json +1 -1
- package/build/WorkerCore.test.compiled.json +1 -1
- package/build/badFeeLib1.test.compiled.json +1 -1
- package/build/badFeeLib10.test.compiled.json +1 -1
- package/build/badFeeLib11.test.compiled.json +1 -1
- package/build/badFeeLib12.test.compiled.json +1 -0
- package/build/badFeeLib2.test.compiled.json +1 -1
- package/build/badFeeLib3.test.compiled.json +1 -1
- package/build/badFeeLib4.test.compiled.json +1 -1
- package/build/badFeeLib5.test.compiled.json +1 -1
- package/build/badFeeLib6.test.compiled.json +1 -1
- package/build/badFeeLib7.test.compiled.json +1 -1
- package/build/badFeeLib8.test.compiled.json +1 -1
- package/build/badFeeLib9.test.compiled.json +1 -1
- package/package.json +9 -6
- package/src/classes/lz/ReceiveEpConfig.fc +1 -1
- package/src/classes/msgdata/LzReceiveStatus.fc +0 -1
- package/src/funC++/actions/call.fc +1 -0
- package/src/funC++/actions/deploy.fc +0 -1
- package/src/funC++/actions/destroy.fc +0 -1
- package/src/funC++/actions/dispatch.fc +0 -1
- package/src/funC++/actions/event.fc +0 -1
- package/src/funC++/actions/payment.fc +0 -1
- package/src/funC++/actions/sendJettons.fc +0 -1
- package/src/funC++/actions/utils.fc +0 -2
- package/src/funC++/baseInterface.fc +0 -2
- package/src/funC++/classlib.fc +6 -81
- package/src/funC++/contractMain.fc +2 -8
- package/src/funC++/dataStructures/DeterministicInsertionCircularQueue.fc +0 -1
- package/src/funC++/dataStructures/PipelinedOutOfOrder.fc +0 -1
- package/src/funC++/handlerCore.fc +2 -6
- package/src/funC++/stringlib.fc +0 -2
- package/src/funC++/testutils.fc +0 -1
- package/src/funC++/txnContext.fc +1 -1
- package/src/funC++/utils.fc +35 -0
- package/src/protocol/channel/callbackOpcodes.fc +10 -0
- package/src/protocol/channel/handler.fc +1032 -0
- package/src/protocol/channel/interface.fc +60 -0
- package/src/protocol/channel/main.fc +39 -0
- package/src/protocol/channel/storage.fc +55 -0
- package/src/protocol/controller/handler.fc +347 -0
- package/src/protocol/controller/interface.fc +25 -0
- package/src/protocol/controller/main.fc +29 -0
- package/src/protocol/controller/storage.fc +31 -0
- package/src/protocol/core/abstract/protocolHandler.fc +110 -0
- package/src/protocol/core/abstract/protocolMain.fc +30 -0
- package/src/protocol/core/baseStorage.fc +33 -0
- package/src/protocol/endpoint/handler.fc +426 -0
- package/src/protocol/endpoint/interface.fc +20 -0
- package/src/protocol/endpoint/main.fc +23 -0
- package/src/protocol/endpoint/storage.fc +37 -0
- package/src/protocol/interfaces.fc +4 -0
- package/src/protocol/msglibs/BytesDecoder.fc +135 -0
- package/src/protocol/msglibs/BytesEncoder.fc +150 -0
- package/src/protocol/msglibs/interface.fc +16 -0
- package/src/protocol/msglibs/simpleMsglib/smlConnection/handler.fc +125 -0
- package/src/protocol/msglibs/simpleMsglib/smlConnection/interface.fc +3 -0
- package/src/protocol/msglibs/simpleMsglib/smlConnection/main.fc +19 -0
- package/src/protocol/msglibs/simpleMsglib/smlConnection/storage.fc +20 -0
- package/src/protocol/msglibs/simpleMsglib/smlManager/handler.fc +281 -0
- package/src/protocol/msglibs/simpleMsglib/smlManager/interface.fc +14 -0
- package/src/protocol/msglibs/simpleMsglib/smlManager/main.fc +24 -0
- package/src/protocol/msglibs/simpleMsglib/smlManager/storage.fc +38 -0
- package/src/protocol/msglibs/ultralightnode/callbackOpcodes.fc +1 -0
- package/src/protocol/msglibs/ultralightnode/feeLibInterface.fc +10 -0
- package/src/protocol/msglibs/ultralightnode/feeLibUtils.fc +51 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/Attestation.fc +49 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/DvnFeesPaidEvent.fc +26 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/ExecutorFeePaidEvent.fc +23 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/InitUln.fc +18 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/InitUlnConnection.fc +62 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/InitUlnManager.fc +18 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/RentRefill.fc +18 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/SetAdminWorkerAddresses.fc +18 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/TreasuryFeeBps.fc +16 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnEvents.fc +26 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnReceiveConfig.fc +249 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnSend.fc +27 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnSendConfig.fc +170 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnVerification.fc +21 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnWorkerFeelibBytecode.fc +16 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnWorkerFeelibEvents.fc +58 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/UlnWorkerFeelibInfo.fc +56 -0
- package/src/protocol/msglibs/ultralightnode/msgdata/VerificationStatus.fc +18 -0
- package/src/protocol/msglibs/ultralightnode/uln/handler.fc +803 -0
- package/src/protocol/msglibs/ultralightnode/uln/interface.fc +63 -0
- package/src/protocol/msglibs/ultralightnode/uln/main.fc +37 -0
- package/src/protocol/msglibs/ultralightnode/uln/storage.fc +43 -0
- package/src/protocol/msglibs/ultralightnode/ulnConnection/handler.fc +600 -0
- package/src/protocol/msglibs/ultralightnode/ulnConnection/interface.fc +36 -0
- package/src/protocol/msglibs/ultralightnode/ulnConnection/main.fc +32 -0
- package/src/protocol/msglibs/ultralightnode/ulnConnection/storage.fc +49 -0
- package/src/protocol/msglibs/ultralightnode/ulnConnection/utils.fc +141 -0
- package/src/protocol/msglibs/ultralightnode/ulnManager/handler.fc +495 -0
- package/src/protocol/msglibs/ultralightnode/ulnManager/interface.fc +59 -0
- package/src/protocol/msglibs/ultralightnode/ulnManager/main.fc +40 -0
- package/src/protocol/msglibs/ultralightnode/ulnManager/storage.fc +44 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/common.fc +27 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/handler.fc +80 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/main.fc +4 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/storage.fc +26 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/handler.fc +123 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/main.fc +4 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/storage.fc +29 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/main.fc +3 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/priceFeedFeeLib/main.fc +1 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/priceFeedFeeLib/storage.fc +39 -0
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/ulnSendWorkerV1.fc +363 -0
- package/src/workers/core/abstract/workerHandler.fc +150 -0
- package/src/workers/core/interface.fc +25 -0
- package/src/workers/core/workerCoreStorage.fc +44 -0
- package/src/workers/dvn/handler.fc +332 -0
- package/src/workers/dvn/interface.fc +25 -0
- package/src/workers/dvn/main.fc +36 -0
- package/src/workers/dvn/storage.fc +27 -0
- package/src/workers/executor/handler.fc +110 -0
- package/src/workers/executor/interface.fc +19 -0
- package/src/workers/executor/main.fc +26 -0
- package/src/workers/executor/storage.fc +19 -0
- package/src/workers/msgdata/ExecuteParams.fc +29 -0
- package/src/workers/msgdata/NativeDrop.fc +16 -0
- package/src/workers/msgdata/ProxyMessage.fc +20 -0
- package/src/workers/msgdata/SetDict.fc +20 -0
- package/src/workers/msgdata/SetQuorum.fc +20 -0
- package/src/workers/msgdata/SignedRequest.fc +18 -0
- package/src/workers/priceFeedCache/handler.fc +114 -0
- package/src/workers/priceFeedCache/interface.fc +4 -0
- package/src/workers/priceFeedCache/main.fc +25 -0
- package/src/workers/priceFeedCache/storage.fc +21 -0
- package/src/workers/proxy/handler.fc +81 -0
- package/src/workers/proxy/interface.fc +11 -0
- package/src/workers/proxy/main.fc +17 -0
- package/src/workers/proxy/storage.fc +21 -0
- package/tests/testMain.fc +0 -1
|
@@ -0,0 +1,803 @@
|
|
|
1
|
+
#include "../../BytesEncoder.fc";
|
|
2
|
+
|
|
3
|
+
#include "../feeLibInterface.fc";
|
|
4
|
+
#include "../feeLibUtils.fc";
|
|
5
|
+
|
|
6
|
+
#include "../msgdata/DvnFeesPaidEvent.fc";
|
|
7
|
+
#include "../msgdata/ExecutorFeePaidEvent.fc";
|
|
8
|
+
#include "../msgdata/InitUln.fc";
|
|
9
|
+
#include "../msgdata/RentRefill.fc";
|
|
10
|
+
#include "../msgdata/TreasuryFeeBps.fc";
|
|
11
|
+
#include "../msgdata/UlnEvents.fc";
|
|
12
|
+
#include "../msgdata/UlnSend.fc";
|
|
13
|
+
#include "../msgdata/UlnSendConfig.fc";
|
|
14
|
+
#include "../msgdata/UlnWorkerFeelibEvents.fc";
|
|
15
|
+
#include "../msgdata/UlnWorkerFeelibInfo.fc";
|
|
16
|
+
|
|
17
|
+
#include "../ulnConnection/interface.fc";
|
|
18
|
+
#include "../ulnManager/interface.fc";
|
|
19
|
+
|
|
20
|
+
#include "../../../interfaces.fc";
|
|
21
|
+
#include "../../../channel/interface.fc";
|
|
22
|
+
#include "../../../core/abstract/protocolHandler.fc";
|
|
23
|
+
|
|
24
|
+
#include "../../../../classes/lz/Packet.fc";
|
|
25
|
+
#include "../../../../classes/msgdata/ExtendedMd.fc";
|
|
26
|
+
#include "../../../../classes/msgdata/LzSend.fc";
|
|
27
|
+
#include "../../../../classes/msgdata/MdAddress.fc";
|
|
28
|
+
#include "../../../../classes/msgdata/MdObj.fc";
|
|
29
|
+
#include "../../../../classes/msgdata/MsglibSendCallback.fc";
|
|
30
|
+
#include "../../../../classes/msgdata/SetAddress.fc";
|
|
31
|
+
|
|
32
|
+
#include "interface.fc";
|
|
33
|
+
#include "storage.fc";
|
|
34
|
+
|
|
35
|
+
const int _quoteWorkersMethodId = 23432;
|
|
36
|
+
;;; ================INTERFACE FUNCTIONS=====================
|
|
37
|
+
|
|
38
|
+
(cell, tuple) _initialize(cell $initUln) impure inline {
|
|
39
|
+
(cell $storage, tuple actions) = preamble();
|
|
40
|
+
|
|
41
|
+
$storage = $storage
|
|
42
|
+
.cl::set(
|
|
43
|
+
Uln::connectionCode,
|
|
44
|
+
$initUln.cl::get<cellRef>(md::InitUln::connectionCode)
|
|
45
|
+
)
|
|
46
|
+
.cl::set(
|
|
47
|
+
Uln::treasuryFeeBps,
|
|
48
|
+
$initUln.cl::get<uint16>(md::InitUln::treasuryFeeBps)
|
|
49
|
+
)
|
|
50
|
+
.cl::set(
|
|
51
|
+
Uln::remainingWorkerSlots,
|
|
52
|
+
Uln::MaxWorkerFeelibs - UlnManager::CONST::MAX_ADMIN_WORKERS
|
|
53
|
+
)
|
|
54
|
+
.cl::set(
|
|
55
|
+
Uln::remainingAdminWorkerSlots,
|
|
56
|
+
UlnManager::CONST::MAX_ADMIN_WORKERS
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return ($storage, actions);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
int _getEventSink() impure {
|
|
63
|
+
return getOwner();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
() assertConnection(cell $ulnSendMd) impure inline {
|
|
67
|
+
cell connectionCode = getContractStorage().cl::get<cellRef>(Uln::connectionCode);
|
|
68
|
+
|
|
69
|
+
cell $connectionInitialStorage = $ulnSendMd
|
|
70
|
+
.cl::get<objRef>(md::UlnSend::connectionInitialStorage);
|
|
71
|
+
|
|
72
|
+
int providedUlnManagerAddress = $connectionInitialStorage
|
|
73
|
+
.cl::get<objRef>(BASE_STORAGE_INDEX)
|
|
74
|
+
.cl::get<address>(BaseStorage::owner);
|
|
75
|
+
|
|
76
|
+
;; By construction, if the bytecode is valid and the uln manager address is correct,
|
|
77
|
+
;; then the uln address cannot be incorrect (assuming no bug in the ULN connection bytecode).
|
|
78
|
+
throw_unless(
|
|
79
|
+
Uln::ERROR::notUlnConnection,
|
|
80
|
+
(providedUlnManagerAddress == getOwner())
|
|
81
|
+
& (computeContractAddress($connectionInitialStorage, connectionCode) == getCaller())
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
cell _failedMsglibSendCallback(cell $lzSend) impure inline {
|
|
86
|
+
return md::MsglibSendCallback::New(
|
|
87
|
+
0,
|
|
88
|
+
0,
|
|
89
|
+
$lzSend,
|
|
90
|
+
empty_cell(),
|
|
91
|
+
empty_cell(),
|
|
92
|
+
0,
|
|
93
|
+
0,
|
|
94
|
+
0,
|
|
95
|
+
0,
|
|
96
|
+
cl::nullObject(),
|
|
97
|
+
Uln::ErrorCode::WORKER_QUOTE_FAILED
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
cell _quote(cell $ulnSendMd, cell $storage) impure inline {
|
|
102
|
+
cell $lzSend = $ulnSendMd.cl::get<objRef>(md::UlnSend::lzSend);
|
|
103
|
+
|
|
104
|
+
int ownerAddress = $storage
|
|
105
|
+
.cl::get<objRef>(BASE_STORAGE_INDEX)
|
|
106
|
+
.cl::get<address>(BaseStorage::owner);
|
|
107
|
+
|
|
108
|
+
(
|
|
109
|
+
int quoteGasLimit,
|
|
110
|
+
int maxMsgBytes,
|
|
111
|
+
int executor,
|
|
112
|
+
cell requiredDVNs,
|
|
113
|
+
cell optionalDVNs,
|
|
114
|
+
int confirmations,
|
|
115
|
+
int isValid
|
|
116
|
+
) = lz::UlnSendConfig::resolveUlnSendConfig(
|
|
117
|
+
$ulnSendMd.cl::get<objRef>(md::UlnSend::customUlnSendConfig),
|
|
118
|
+
$storage.cl::get<objRef>(Uln::defaultUlnSendConfig)
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
ifnot (isValid) {
|
|
122
|
+
return md::MdAddress::New(
|
|
123
|
+
_failedMsglibSendCallback($lzSend),
|
|
124
|
+
ownerAddress
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
int messageBytes = lz::Packet::_messageBytes($lzSend.cl::get<objRef>(md::LzSend::packet));
|
|
129
|
+
|
|
130
|
+
tuple returnStack = unsafeTuple([null()]);
|
|
131
|
+
|
|
132
|
+
if (messageBytes <= maxMsgBytes) {
|
|
133
|
+
returnStack = safePackedInputsRunVm(
|
|
134
|
+
unsafeTuple([
|
|
135
|
+
$storage,
|
|
136
|
+
$lzSend,
|
|
137
|
+
executor,
|
|
138
|
+
requiredDVNs,
|
|
139
|
+
optionalDVNs,
|
|
140
|
+
confirmations,
|
|
141
|
+
messageBytes,
|
|
142
|
+
$lzSend.cl::get<objRef>(md::LzSend::extraOptions),
|
|
143
|
+
$lzSend.cl::get<objRef>(md::LzSend::enforcedOptions)
|
|
144
|
+
]),
|
|
145
|
+
_quoteWorkersMethodId,
|
|
146
|
+
1,
|
|
147
|
+
my_code().begin_parse(),
|
|
148
|
+
quoteGasLimit
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
cell $msglibSendCallback = returnStack.cell_at(0);
|
|
153
|
+
ifnot ($msglibSendCallback.is_cell()) {
|
|
154
|
+
return md::MdAddress::New(
|
|
155
|
+
_failedMsglibSendCallback($lzSend),
|
|
156
|
+
ownerAddress
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return md::MdAddress::New(
|
|
161
|
+
$msglibSendCallback,
|
|
162
|
+
ownerAddress
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
;; caller is responsible for asserting the worker exists
|
|
167
|
+
cell _removeWorker(cell $storage, cell $workerFeelibInfo) impure inline {
|
|
168
|
+
int workerAddress = $workerFeelibInfo.cl::get<address>(UlnWorkerFeelibInfo::workerAddress);
|
|
169
|
+
int workerSlotField = $workerFeelibInfo.cl::get<bool>(UlnWorkerFeelibInfo::isAdmin)
|
|
170
|
+
? Uln::remainingAdminWorkerSlots
|
|
171
|
+
: Uln::remainingWorkerSlots;
|
|
172
|
+
return $storage
|
|
173
|
+
.cl::nestedDict256::delete(Uln::workerFeelibInfos, workerAddress)
|
|
174
|
+
.cl::set( workerSlotField, $storage.cl::get<uint16>(workerSlotField) + 1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
(int, cell) _quoteWorker(
|
|
178
|
+
cell $storage,
|
|
179
|
+
int workerAddress,
|
|
180
|
+
cell $path,
|
|
181
|
+
int confirmations,
|
|
182
|
+
int packetBytes,
|
|
183
|
+
cell $extraOptions,
|
|
184
|
+
cell $enforcedOptions
|
|
185
|
+
) impure inline_ref method_id {
|
|
186
|
+
(cell $workerInfo, int workerExists) = $storage.cl::nestedDict256::get<cellRef>(
|
|
187
|
+
Uln::workerFeelibInfos,
|
|
188
|
+
workerAddress
|
|
189
|
+
);
|
|
190
|
+
ifnot (workerExists) {
|
|
191
|
+
return (-1, null());
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
(cell $friendInfo, int friendExists) = ($workerInfo, workerExists);
|
|
195
|
+
int friendWorkerAddress = $workerInfo
|
|
196
|
+
.cl::get<address>(UlnWorkerFeelibInfo::friendWorkerAddress);
|
|
197
|
+
|
|
198
|
+
ifnot (friendWorkerAddress == NULLADDRESS) {
|
|
199
|
+
($friendInfo, friendExists) = $storage.cl::nestedDict256::get<cellRef>(
|
|
200
|
+
Uln::workerFeelibInfos,
|
|
201
|
+
friendWorkerAddress
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
ifnot (friendExists) {
|
|
205
|
+
return (-1, null());
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
tuple returnStack = safePackedInputsRunVm(
|
|
209
|
+
unsafeTuple(
|
|
210
|
+
[
|
|
211
|
+
$workerInfo.cl::get<objRef>(UlnWorkerFeelibInfo::workerFeelibStorage),
|
|
212
|
+
$friendInfo,
|
|
213
|
+
$path,
|
|
214
|
+
confirmations,
|
|
215
|
+
packetBytes,
|
|
216
|
+
$extraOptions,
|
|
217
|
+
$enforcedOptions
|
|
218
|
+
]
|
|
219
|
+
),
|
|
220
|
+
UlnWorkerInterface::quote,
|
|
221
|
+
1,
|
|
222
|
+
$workerInfo.cl::get<cellRef>(UlnWorkerFeelibInfo::workerFeelibBytecode).begin_parse(),
|
|
223
|
+
MAX_U32 ;; gas limit doesn't matter for the inner call
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
tuple retVal = returnStack.tuple_at(0);
|
|
227
|
+
;; if it's not a tuple, then the worker returned an error or went OOG
|
|
228
|
+
ifnot (retVal.is_tuple()) {
|
|
229
|
+
return (-1, null());
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
;; the tuple must have exactly two items
|
|
233
|
+
ifnot (retVal.tlen() == 2) {
|
|
234
|
+
return (-1, null());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
;; the first item must be an int
|
|
238
|
+
int fee = retVal.int_at(0);
|
|
239
|
+
ifnot (fee.is_int()) {
|
|
240
|
+
return (-1, null());
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
;; the second item must be a cell or null
|
|
244
|
+
cell event = retVal.cell_at(1);
|
|
245
|
+
ifnot ((event.is_cell()) | (event.is_null())) {
|
|
246
|
+
return (-1, null());
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return (fee, event);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
;; return null on failure, actions on success
|
|
253
|
+
;; tuple _quoteWorkers(cell $lzSend, int executor, cell requiredDVNs, cell optionalDVNs) impure inline {
|
|
254
|
+
cell _quoteWorkers(tuple args) impure inline method_id(23432) {
|
|
255
|
+
cell $storage = args.cell_at(0);
|
|
256
|
+
cell $lzSend = args.cell_at(1);
|
|
257
|
+
int executor = args.int_at(2);
|
|
258
|
+
cell requiredDVNsCell = args.cell_at(3);
|
|
259
|
+
cell optionalDVNsCell = args.cell_at(4);
|
|
260
|
+
int confirmations = args.int_at(5);
|
|
261
|
+
int packetBytes = args.int_at(6);
|
|
262
|
+
cell $extraOptions = args.cell_at(7);
|
|
263
|
+
cell $enforcedOptions = args.cell_at(8);
|
|
264
|
+
;; quote the executor first
|
|
265
|
+
int totalNativeFee = 0;
|
|
266
|
+
|
|
267
|
+
slice requiredDVNs = requiredDVNsCell.begin_parse();
|
|
268
|
+
slice optionalDVNs = optionalDVNsCell.begin_parse();
|
|
269
|
+
|
|
270
|
+
cell $packet = $lzSend.cl::get<objRef>(md::LzSend::packet);
|
|
271
|
+
cell $path = $packet.cl::get<cellRef>(lz::Packet::path);
|
|
272
|
+
|
|
273
|
+
tuple payeesInfo = empty_tuple();
|
|
274
|
+
tuple workerEvents = UlnWorkerFeelibEventsBuilder::create();
|
|
275
|
+
|
|
276
|
+
while (requiredDVNs.slice_empty?() == false) {
|
|
277
|
+
int requiredDVNAddress = requiredDVNs~AddressList::next();
|
|
278
|
+
(int nativeFee, cell eventBody) = _quoteWorker(
|
|
279
|
+
$storage,
|
|
280
|
+
requiredDVNAddress,
|
|
281
|
+
$path,
|
|
282
|
+
confirmations,
|
|
283
|
+
packetBytes,
|
|
284
|
+
$extraOptions,
|
|
285
|
+
$enforcedOptions
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
if (nativeFee < 0) {
|
|
289
|
+
return null();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
totalNativeFee += nativeFee;
|
|
293
|
+
payeesInfo = payeesInfo.tpush(unsafeTuple([requiredDVNAddress, nativeFee]));
|
|
294
|
+
workerEvents = workerEvents
|
|
295
|
+
.UlnWorkerFeelibEventsBuilder::push(requiredDVNAddress, eventBody);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
while (optionalDVNs.slice_empty?() == false) {
|
|
299
|
+
int optionalDVNAddress = optionalDVNs~AddressList::next();
|
|
300
|
+
(int nativeFee, cell eventBody) = _quoteWorker(
|
|
301
|
+
$storage,
|
|
302
|
+
optionalDVNAddress,
|
|
303
|
+
$path,
|
|
304
|
+
confirmations,
|
|
305
|
+
packetBytes,
|
|
306
|
+
$extraOptions,
|
|
307
|
+
$enforcedOptions
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
if (nativeFee < 0) {
|
|
311
|
+
return null();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
payeesInfo = payeesInfo.tpush(unsafeTuple([optionalDVNAddress, nativeFee]));
|
|
315
|
+
totalNativeFee += nativeFee;
|
|
316
|
+
|
|
317
|
+
workerEvents = workerEvents
|
|
318
|
+
.UlnWorkerFeelibEventsBuilder::push(optionalDVNAddress, eventBody);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
;; create the dvnPaidEvent
|
|
322
|
+
cell $dvnsFeesPaidEvent = DvnFeesPaidEvent::New(
|
|
323
|
+
requiredDVNsCell,
|
|
324
|
+
optionalDVNsCell,
|
|
325
|
+
serializePayees(payeesInfo)
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
(int executorFee, cell eventBody) = _quoteWorker(
|
|
329
|
+
$storage,
|
|
330
|
+
executor,
|
|
331
|
+
$path,
|
|
332
|
+
confirmations,
|
|
333
|
+
packetBytes,
|
|
334
|
+
$extraOptions,
|
|
335
|
+
$enforcedOptions
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
if (executorFee < 0) {
|
|
339
|
+
return null();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
;; add the executor fee
|
|
343
|
+
payeesInfo = payeesInfo.tpush(unsafeTuple([executor, executorFee]));
|
|
344
|
+
totalNativeFee += executorFee;
|
|
345
|
+
|
|
346
|
+
;; add events from executor to workerEvents
|
|
347
|
+
workerEvents = workerEvents
|
|
348
|
+
.UlnWorkerFeelibEventsBuilder::push(executor, eventBody);
|
|
349
|
+
|
|
350
|
+
;; create the executorPaidEvent
|
|
351
|
+
cell $executorFeePaidEvent = ExecutorFeePaidEvent::New(executor, executorFee);
|
|
352
|
+
|
|
353
|
+
;; Handle treasury fee
|
|
354
|
+
int treasuryFee = totalNativeFee * $storage.cl::get<uint16>(Uln::treasuryFeeBps) / 10000;
|
|
355
|
+
payeesInfo = payeesInfo.tpush(
|
|
356
|
+
unsafeTuple([
|
|
357
|
+
$storage.cl::get<objRef>(BASE_STORAGE_INDEX).cl::get<address>(BaseStorage::owner),
|
|
358
|
+
treasuryFee
|
|
359
|
+
])
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
cell ret = md::MsglibSendCallback::New(
|
|
363
|
+
totalNativeFee + treasuryFee,
|
|
364
|
+
0,
|
|
365
|
+
$lzSend,
|
|
366
|
+
BytesEncoder::build<PacketV1>($packet).BytesEncoder::serialize(),
|
|
367
|
+
serializePayees(payeesInfo),
|
|
368
|
+
PacketV1::nonceOffsetBytes,
|
|
369
|
+
PacketV1::nonceBytes,
|
|
370
|
+
PacketV1::guidOffsetBytes,
|
|
371
|
+
PacketV1::guidBytes,
|
|
372
|
+
UlnEvents::New(
|
|
373
|
+
UlnWorkerFeelibEvents::FromBuilder(workerEvents),
|
|
374
|
+
$dvnsFeesPaidEvent,
|
|
375
|
+
$executorFeePaidEvent
|
|
376
|
+
),
|
|
377
|
+
Channel::NO_ERROR
|
|
378
|
+
);
|
|
379
|
+
return ret;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
;;; ================PERMISSION FUNCTIONS=====================
|
|
383
|
+
|
|
384
|
+
() _checkPermissions(int op, cell $md) impure inline {
|
|
385
|
+
if (op == Uln::OP::ULN_SEND) {
|
|
386
|
+
return assertConnection($md);
|
|
387
|
+
} elseif (
|
|
388
|
+
(op == Uln::OP::ULN_VERIFY)
|
|
389
|
+
| (op == Uln::OP::ULN_COMMIT_PACKET)
|
|
390
|
+
) {
|
|
391
|
+
return ();
|
|
392
|
+
} elseif (
|
|
393
|
+
(op == Uln::OP::DEREGISTER_WORKER_FEELIB)
|
|
394
|
+
| (op == Uln::OP::COLLECT_WORKER_RENT)
|
|
395
|
+
| (op == Uln::OP::SET_WORKER_FEELIB_STORAGE)
|
|
396
|
+
| (op == Uln::OP::REFILL_WORKER_RENT)
|
|
397
|
+
| (op == Uln::OP::GC_ATTESTATIONS)
|
|
398
|
+
) {
|
|
399
|
+
return ();
|
|
400
|
+
} elseif (
|
|
401
|
+
(op == Uln::OP::SET_DEFAULT_ULN_RECEIVE_CONFIG)
|
|
402
|
+
| (op == Uln::OP::SET_DEFAULT_ULN_SEND_CONFIG)
|
|
403
|
+
| (op == Uln::OP::UPDATE_WORKER_FEELIB)
|
|
404
|
+
| (op == Uln::OP::SET_TREASURY_FEE_BPS)
|
|
405
|
+
) {
|
|
406
|
+
return assertOwner();
|
|
407
|
+
} else {
|
|
408
|
+
;; we must put a check for all opcodes to make sure we don't
|
|
409
|
+
;; mistakenly miss an opp code's permissions
|
|
410
|
+
throw(BaseInterface::ERROR::invalidOpcode);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
;;; ==========================HANDLERS=====================================
|
|
415
|
+
|
|
416
|
+
tuple ulnQuote(cell $ulnSendMd) impure inline method_id {
|
|
417
|
+
(cell $storage, tuple actions) = preamble();
|
|
418
|
+
|
|
419
|
+
actions~pushAction<call>(
|
|
420
|
+
$ulnSendMd.cl::get<address>(md::UlnSend::forwardingAddress),
|
|
421
|
+
Msglib::OP::RETURN_QUOTE,
|
|
422
|
+
_quote($ulnSendMd, $storage)
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
return actions;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
tuple ulnSend(cell $ulnSendMd) impure inline method_id {
|
|
429
|
+
(cell $storage, tuple actions) = preamble();
|
|
430
|
+
|
|
431
|
+
actions~pushAction<call>(
|
|
432
|
+
$ulnSendMd.cl::get<address>(md::UlnSend::forwardingAddress),
|
|
433
|
+
Channel::OP::MSGLIB_SEND_CALLBACK,
|
|
434
|
+
_quote($ulnSendMd, $storage)
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
return actions;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
;; @in_opcode Msglibs::OP::ULN_COMMIT_VERIFICATION
|
|
441
|
+
;; @in frame
|
|
442
|
+
;; @in $mdAddress { address: UlnConnectionAddress, md: Packet }
|
|
443
|
+
;; @permissions permissionless
|
|
444
|
+
;; @out_actions call commit on connection
|
|
445
|
+
tuple ulnCommitPacket(cell $mdAddress) impure inline method_id {
|
|
446
|
+
(cell $storage, tuple actions) = preamble();
|
|
447
|
+
|
|
448
|
+
actions~pushAction<call>(
|
|
449
|
+
$mdAddress.cl::get<address>(md::MdAddress::address),
|
|
450
|
+
UlnConnection::OP::ULN_CONNECTION_COMMIT_PACKET,
|
|
451
|
+
md::MdObj::New(
|
|
452
|
+
$mdAddress.cl::get<objRef>(md::MdAddress::md),
|
|
453
|
+
$storage.cl::get<objRef>(Uln::defaultUlnReceiveConfig)
|
|
454
|
+
)
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
return actions;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
;; @in_opcode Msglibs::OP::VERIFY
|
|
461
|
+
;; @in external caller
|
|
462
|
+
;; @in $mdAddress { address: UlnConnectionAddress, md: Verification }
|
|
463
|
+
;; @permissions permissionless
|
|
464
|
+
;; @out_actions call verify on connection
|
|
465
|
+
;; @notice this is an optional function that will
|
|
466
|
+
;; call ulnConnectionVerify on the connection using a default config
|
|
467
|
+
tuple ulnVerify(cell $mdAddress) impure inline method_id {
|
|
468
|
+
(cell $storage, tuple actions) = preamble();
|
|
469
|
+
|
|
470
|
+
actions~pushAction<call>(
|
|
471
|
+
$mdAddress.cl::get<address>(md::MdAddress::address),
|
|
472
|
+
UlnConnection::OP::ULN_CONNECTION_VERIFY,
|
|
473
|
+
md::ExtendedMd::New(
|
|
474
|
+
$mdAddress.cl::get<objRef>(md::MdAddress::md),
|
|
475
|
+
$storage.cl::get<objRef>(Uln::defaultUlnReceiveConfig),
|
|
476
|
+
getCaller()
|
|
477
|
+
)
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
return actions;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
() _setWorkerInfo(cell $workerFeelibInfo) impure inline_ref {
|
|
484
|
+
cell $storage = getContractStorage();
|
|
485
|
+
int workerAddress = $workerFeelibInfo.cl::get<address>(UlnWorkerFeelibInfo::workerAddress);
|
|
486
|
+
|
|
487
|
+
;; Restrict the size of the new storage to prevent DoS of our contract storage.
|
|
488
|
+
;; The total worker bytecode size is capped by UlnManager::CONST::MAX_CUMULATIVE_BYTECODE_CELLS
|
|
489
|
+
;; and enforced by the UlnManager, so here the only thing we need to check is the storage size
|
|
490
|
+
;; of the workers, excluding their bytecode
|
|
491
|
+
(_, _, _, int success) = compute_data_size?(
|
|
492
|
+
$workerFeelibInfo.cl::set(UlnWorkerFeelibInfo::workerFeelibBytecode, empty_cell()),
|
|
493
|
+
Uln::WorkerFeelibInfo::MaxCells
|
|
494
|
+
);
|
|
495
|
+
|
|
496
|
+
throw_unless(Uln::ERROR::invalidWorkerStorage, success);
|
|
497
|
+
|
|
498
|
+
setContractStorage(
|
|
499
|
+
$storage
|
|
500
|
+
.cl::nestedDict256::setRef(
|
|
501
|
+
Uln::workerFeelibInfos,
|
|
502
|
+
workerAddress,
|
|
503
|
+
$workerFeelibInfo
|
|
504
|
+
)
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
tuple updateWorkerFeelib(cell $UlnWorkerFeelibInfo) impure inline method_id {
|
|
509
|
+
(cell $storage, tuple actions) = preamble();
|
|
510
|
+
int workerAddress = $UlnWorkerFeelibInfo.cl::get<address>(UlnWorkerFeelibInfo::workerAddress);
|
|
511
|
+
|
|
512
|
+
(cell $existingWorkerFeelibInfo, int exists) = cl::nestedDict256::get<cellRef>(
|
|
513
|
+
$storage,
|
|
514
|
+
Uln::workerFeelibInfos,
|
|
515
|
+
workerAddress
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
ifnot (exists) {
|
|
519
|
+
int isAdmin = $UlnWorkerFeelibInfo.cl::get<bool>(UlnWorkerFeelibInfo::isAdmin);
|
|
520
|
+
int workerSlotField = isAdmin ? Uln::remainingAdminWorkerSlots : Uln::remainingWorkerSlots;
|
|
521
|
+
int remainingWorkerSlots = $storage.cl::get<uint16>(workerSlotField);
|
|
522
|
+
|
|
523
|
+
if (remainingWorkerSlots == 0) {
|
|
524
|
+
;; exit early if there are no remaining worker slots
|
|
525
|
+
actions~pushAction<event>(
|
|
526
|
+
Uln::event::ULN_WORKER_SLOTS_FULL,
|
|
527
|
+
$UlnWorkerFeelibInfo
|
|
528
|
+
);
|
|
529
|
+
return actions;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
ifnot (isAdmin) {
|
|
533
|
+
;; if it doesn't exist, we must collect the initial rent deposit
|
|
534
|
+
int initialRent = $UlnWorkerFeelibInfo.cl::get<coins>(UlnWorkerFeelibInfo::rentBalance);
|
|
535
|
+
|
|
536
|
+
throw_unless(Uln::ERROR::insufficientRent, initialRent >= Uln::CONST::INITIAL_RENT_NANOS);
|
|
537
|
+
|
|
538
|
+
actions~pushAction<payment>(
|
|
539
|
+
getOwner(),
|
|
540
|
+
initialRent,
|
|
541
|
+
0
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
$UlnWorkerFeelibInfo = $UlnWorkerFeelibInfo.cl::set(
|
|
546
|
+
UlnWorkerFeelibInfo::lastRentTimestamp,
|
|
547
|
+
now()
|
|
548
|
+
);
|
|
549
|
+
|
|
550
|
+
setContractStorage($storage.cl::set(workerSlotField, remainingWorkerSlots - 1));
|
|
551
|
+
} else {
|
|
552
|
+
;; Do not allow workers to arbitrarily change their rent information
|
|
553
|
+
$UlnWorkerFeelibInfo = $UlnWorkerFeelibInfo
|
|
554
|
+
.cl::set(
|
|
555
|
+
UlnWorkerFeelibInfo::rentBalance,
|
|
556
|
+
$existingWorkerFeelibInfo.cl::get<coins>(UlnWorkerFeelibInfo::rentBalance)
|
|
557
|
+
)
|
|
558
|
+
.cl::set(
|
|
559
|
+
UlnWorkerFeelibInfo::lastRentTimestamp,
|
|
560
|
+
$existingWorkerFeelibInfo.cl::get<uint64>(UlnWorkerFeelibInfo::lastRentTimestamp)
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
_setWorkerInfo($UlnWorkerFeelibInfo);
|
|
565
|
+
|
|
566
|
+
actions~pushAction<event>(
|
|
567
|
+
Uln::event::ULN_WORKER_REGISTERED,
|
|
568
|
+
$UlnWorkerFeelibInfo
|
|
569
|
+
);
|
|
570
|
+
|
|
571
|
+
return actions;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
tuple deregisterWorkerFeelib(cell $empty) impure inline method_id {
|
|
575
|
+
(cell $storage, tuple actions) = preamble();
|
|
576
|
+
|
|
577
|
+
int workerAddress = getCaller();
|
|
578
|
+
(cell $UlnWorkerFeelibInfo, int exists) = cl::nestedDict256::get<cellRef>(
|
|
579
|
+
$storage,
|
|
580
|
+
Uln::workerFeelibInfos,
|
|
581
|
+
workerAddress
|
|
582
|
+
);
|
|
583
|
+
|
|
584
|
+
if (exists) {
|
|
585
|
+
setContractStorage(
|
|
586
|
+
_removeWorker($storage, $UlnWorkerFeelibInfo)
|
|
587
|
+
);
|
|
588
|
+
actions~pushAction<event>(
|
|
589
|
+
Uln::event::ULN_WORKER_DEREGISTERED,
|
|
590
|
+
$UlnWorkerFeelibInfo
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
return actions;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
;; This function handles ALL worker configs including priceFeed updates
|
|
598
|
+
;; @out_actions event
|
|
599
|
+
tuple setWorkerFeelibStorage(cell $newStorage) impure inline method_id {
|
|
600
|
+
(cell $storage, tuple actions) = preamble();
|
|
601
|
+
|
|
602
|
+
(cell $workerInfo, int exists) = $storage.cl::nestedDict256::get<cellRef>(
|
|
603
|
+
Uln::workerFeelibInfos,
|
|
604
|
+
getCaller()
|
|
605
|
+
);
|
|
606
|
+
throw_unless(Uln::ERROR::nonexistentWorker, exists);
|
|
607
|
+
|
|
608
|
+
cell $updatedWorkerInfo = $workerInfo.cl::set(
|
|
609
|
+
UlnWorkerFeelibInfo::workerFeelibStorage,
|
|
610
|
+
$newStorage
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
;; _setWorkerInfo does size assertions on worker storage
|
|
614
|
+
_setWorkerInfo($updatedWorkerInfo);
|
|
615
|
+
|
|
616
|
+
setContractStorage(
|
|
617
|
+
$storage
|
|
618
|
+
.cl::nestedDict256::setRef(
|
|
619
|
+
Uln::workerFeelibInfos,
|
|
620
|
+
getCaller(),
|
|
621
|
+
$updatedWorkerInfo
|
|
622
|
+
)
|
|
623
|
+
);
|
|
624
|
+
|
|
625
|
+
actions~pushAction<event>(
|
|
626
|
+
Uln::event::ULN_WORKER_STORAGE_SET,
|
|
627
|
+
$updatedWorkerInfo
|
|
628
|
+
);
|
|
629
|
+
|
|
630
|
+
actions~pushAction<call>(
|
|
631
|
+
getCaller(),
|
|
632
|
+
Uln::OP::SET_WORKER_FEELIB_STORAGE_CALLBACK,
|
|
633
|
+
$newStorage
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
return actions;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
tuple refillWorkerRent(cell $rentRefill) {
|
|
640
|
+
(cell $storage, tuple actions) = preamble();
|
|
641
|
+
|
|
642
|
+
int workerAddress = $rentRefill.cl::get<address>(md::RentRefill::address);
|
|
643
|
+
int amount = $rentRefill.cl::get<coins>(md::RentRefill::amount);
|
|
644
|
+
(cell $workerInfo, int exists) = cl::nestedDict256::get<cellRef>(
|
|
645
|
+
$storage,
|
|
646
|
+
Uln::workerFeelibInfos,
|
|
647
|
+
workerAddress
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
throw_unless(Uln::ERROR::nonexistentWorker, exists);
|
|
651
|
+
|
|
652
|
+
int currentRentBalance = $workerInfo.cl::get<coins>(UlnWorkerFeelibInfo::rentBalance);
|
|
653
|
+
|
|
654
|
+
_setWorkerInfo(
|
|
655
|
+
$workerInfo.cl::set(UlnWorkerFeelibInfo::rentBalance, currentRentBalance + amount)
|
|
656
|
+
);
|
|
657
|
+
|
|
658
|
+
actions~pushAction<payment>(
|
|
659
|
+
getOwner(),
|
|
660
|
+
amount,
|
|
661
|
+
0
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
actions~pushAction<event>(
|
|
665
|
+
Uln::event::ULN_WORKER_RENT_REFILLED,
|
|
666
|
+
$rentRefill
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
return actions;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
tuple collectWorkerRent(cell $setAddress) impure inline method_id {
|
|
673
|
+
(cell $storage, tuple actions) = preamble();
|
|
674
|
+
|
|
675
|
+
(cell $workerInfo, int exists) = cl::nestedDict256::get<cellRef>(
|
|
676
|
+
$storage,
|
|
677
|
+
Uln::workerFeelibInfos,
|
|
678
|
+
$setAddress.cl::get<address>(md::SetAddress::address)
|
|
679
|
+
);
|
|
680
|
+
|
|
681
|
+
throw_unless(Uln::ERROR::nonexistentWorker, exists);
|
|
682
|
+
|
|
683
|
+
;; Admins do not pay rent
|
|
684
|
+
if ($workerInfo.cl::get<bool>(UlnWorkerFeelibInfo::isAdmin)) {
|
|
685
|
+
return emptyActions();
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
int currentTimestamp = now();
|
|
689
|
+
int elapsedTimestamp = currentTimestamp - $workerInfo.cl::get<uint64>(UlnWorkerFeelibInfo::lastRentTimestamp);
|
|
690
|
+
throw_unless(Uln::ERROR::invalidTimestamp, elapsedTimestamp > 0);
|
|
691
|
+
|
|
692
|
+
int totalRentOwed = elapsedTimestamp * Uln::CONST::RENT_NANOS_PER_SECOND;
|
|
693
|
+
int currentRentBalance = $workerInfo.cl::get<coins>(UlnWorkerFeelibInfo::rentBalance);
|
|
694
|
+
|
|
695
|
+
;; if rentBalance is greater than totalRentOwed, we can update rentBalance and lastRentTimestamp
|
|
696
|
+
;; else we must delete(evict) the worker from the workerInfos
|
|
697
|
+
if (currentRentBalance >= totalRentOwed) {
|
|
698
|
+
$workerInfo = $workerInfo
|
|
699
|
+
.cl::set(UlnWorkerFeelibInfo::rentBalance, currentRentBalance - totalRentOwed)
|
|
700
|
+
.cl::set(UlnWorkerFeelibInfo::lastRentTimestamp, currentTimestamp);
|
|
701
|
+
|
|
702
|
+
;; update workerInfo in storage
|
|
703
|
+
_setWorkerInfo($workerInfo);
|
|
704
|
+
|
|
705
|
+
actions~pushAction<event>(
|
|
706
|
+
Uln::event::ULN_COLLECT_WORKER_RENT,
|
|
707
|
+
$workerInfo
|
|
708
|
+
);
|
|
709
|
+
} else {
|
|
710
|
+
setContractStorage(
|
|
711
|
+
_removeWorker($storage, $workerInfo)
|
|
712
|
+
);
|
|
713
|
+
|
|
714
|
+
actions~pushAction<event>(
|
|
715
|
+
Uln::event::ULN_WORKER_EVICTED,
|
|
716
|
+
$workerInfo
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return actions;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
tuple setDefaultUlnSendConfig(cell $ulnSendConfig) impure inline method_id {
|
|
724
|
+
(cell $storage, tuple actions) = preamble();
|
|
725
|
+
|
|
726
|
+
cell $sanitizedUlnSendConfig = UlnSendConfig::sanitize($ulnSendConfig);
|
|
727
|
+
|
|
728
|
+
setContractStorage(
|
|
729
|
+
$storage.cl::set(
|
|
730
|
+
Uln::defaultUlnSendConfig,
|
|
731
|
+
$sanitizedUlnSendConfig
|
|
732
|
+
)
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
actions~pushAction<event>(
|
|
736
|
+
Uln::event::ULN_DEFAULT_SEND_CONFIG_SET,
|
|
737
|
+
$sanitizedUlnSendConfig
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
return actions;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
tuple setDefaultUlnReceiveConfig(cell $ulnReceiveConfig) impure inline method_id {
|
|
744
|
+
(cell $storage, tuple actions) = preamble();
|
|
745
|
+
|
|
746
|
+
cell $sanitizedUlnReceiveConfig = UlnReceiveConfig::sanitize($ulnReceiveConfig);
|
|
747
|
+
|
|
748
|
+
setContractStorage(
|
|
749
|
+
$storage.cl::set(
|
|
750
|
+
Uln::defaultUlnReceiveConfig,
|
|
751
|
+
$sanitizedUlnReceiveConfig
|
|
752
|
+
)
|
|
753
|
+
);
|
|
754
|
+
actions~pushAction<event>(
|
|
755
|
+
Uln::event::ULN_DEFAULT_RECEIVE_CONFIG_SET,
|
|
756
|
+
$sanitizedUlnReceiveConfig
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
return actions;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
tuple setTreasuryFeeBps(cell $treasuryFeeBps) impure inline method_id {
|
|
763
|
+
(cell $storage, tuple actions) = preamble();
|
|
764
|
+
|
|
765
|
+
int treasuryFeeBps = $treasuryFeeBps.cl::get<uint16>(md::TreasuryFeeBps::treasuryFeeBps);
|
|
766
|
+
|
|
767
|
+
throw_unless(Uln::ERROR::invalidTreasuryFeeBps, treasuryFeeBps <= 10000);
|
|
768
|
+
|
|
769
|
+
setContractStorage(
|
|
770
|
+
$storage.cl::set(
|
|
771
|
+
Uln::treasuryFeeBps,
|
|
772
|
+
treasuryFeeBps
|
|
773
|
+
)
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
actions~pushAction<event>(
|
|
777
|
+
Uln::event::ULN_TREASURY_FEE_BPS_SET,
|
|
778
|
+
$treasuryFeeBps
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
return actions;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
;; Send the default config to the ULN connection to allow it to garbage collect
|
|
785
|
+
;; attestations from DVNs that were removed from the configuration
|
|
786
|
+
tuple garbageCollectInvalidAttestations(cell $mdAddress) impure inline method_id {
|
|
787
|
+
(cell $storage, tuple actions) = preamble();
|
|
788
|
+
|
|
789
|
+
actions~pushAction<call>(
|
|
790
|
+
$mdAddress.cl::get<address>(md::MdAddress::address),
|
|
791
|
+
UlnConnection::OP::GARBAGE_COLLECT_INVALID_ATTESTATIONS,
|
|
792
|
+
md::MdObj::New(
|
|
793
|
+
$mdAddress.cl::get<objRef>(md::MdAddress::md),
|
|
794
|
+
$storage.cl::get<objRef>(Uln::defaultUlnReceiveConfig)
|
|
795
|
+
)
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
return actions;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
(int, int, int) version() impure method_id {
|
|
802
|
+
return (3, 0, 2);
|
|
803
|
+
}
|