-
Notifications
You must be signed in to change notification settings - Fork 156
Expand file tree
/
Copy pathcontract_def.h
More file actions
548 lines (463 loc) · 21.9 KB
/
contract_def.h
File metadata and controls
548 lines (463 loc) · 21.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
#pragma once
////////// Smart contracts \\\\\\\\\\
// The order in this file is very important, because it restricts what is available to the contracts.
// For example, a contract may only call a contract with lower index, which is enforced by order of
// include / availability of definition.
// Additionally, most types, functions, and variables of the core have to be defined after including
// the contract to keep them unavailable in the contract code.
// With no other includes before, the following are the only headers available to contracts.
// When adding something, be cautious to keep access of contracts limited to safe features only.
#include "pre_qpi_def.h"
#include "contracts/qpi.h"
#include "qpi_proposal_voting.h"
// make interfaces to oracles available for all contracts
#include "oracle_core/oracle_interfaces_def.h"
#define QX_CONTRACT_INDEX 1
#define CONTRACT_INDEX QX_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QX
#define CONTRACT_STATE2_TYPE QX2
#include "contracts/Qx.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QUOTTERY_CONTRACT_INDEX 2
#define CONTRACT_INDEX QUOTTERY_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QUOTTERY
#define CONTRACT_STATE2_TYPE QUOTTERY2
#include "contracts/Quottery.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define RANDOM_CONTRACT_INDEX 3
#define CONTRACT_INDEX RANDOM_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE RANDOM
#define CONTRACT_STATE2_TYPE RANDOM2
#include "contracts/Random.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QUTIL_CONTRACT_INDEX 4
#define CONTRACT_INDEX QUTIL_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QUTIL
#define CONTRACT_STATE2_TYPE QUTIL2
#include "contracts/QUtil.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define MLM_CONTRACT_INDEX 5
#define CONTRACT_INDEX MLM_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE MLM
#define CONTRACT_STATE2_TYPE MLM2
#include "contracts/MyLastMatch.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define GQMPROP_CONTRACT_INDEX 6
#define CONTRACT_INDEX GQMPROP_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE GQMPROP
#define CONTRACT_STATE2_TYPE GQMPROP2
#include "contracts/GeneralQuorumProposal.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define SWATCH_CONTRACT_INDEX 7
#define CONTRACT_INDEX SWATCH_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE SWATCH
#define CONTRACT_STATE2_TYPE SWATCH2
#include "contracts/SupplyWatcher.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define CCF_CONTRACT_INDEX 8
#define CONTRACT_INDEX CCF_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE CCF
#define CONTRACT_STATE2_TYPE CCF2
#include "contracts/ComputorControlledFund.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QEARN_CONTRACT_INDEX 9
#define CONTRACT_INDEX QEARN_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QEARN
#define CONTRACT_STATE2_TYPE QEARN2
#include "contracts/Qearn.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QVAULT_CONTRACT_INDEX 10
#define CONTRACT_INDEX QVAULT_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QVAULT
#define CONTRACT_STATE2_TYPE QVAULT2
#include "contracts/QVAULT.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define MSVAULT_CONTRACT_INDEX 11
#define CONTRACT_INDEX MSVAULT_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE MSVAULT
#define CONTRACT_STATE2_TYPE MSVAULT2
#include "contracts/MsVault.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QBAY_CONTRACT_INDEX 12
#define CONTRACT_INDEX QBAY_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QBAY
#define CONTRACT_STATE2_TYPE QBAY2
#include "contracts/Qbay.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QSWAP_CONTRACT_INDEX 13
#define CONTRACT_INDEX QSWAP_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QSWAP
#define CONTRACT_STATE2_TYPE QSWAP2
#include "contracts/Qswap.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define NOST_CONTRACT_INDEX 14
#define CONTRACT_INDEX NOST_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE NOST
#define CONTRACT_STATE2_TYPE NOST2
#include "contracts/Nostromo.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QDRAW_CONTRACT_INDEX 15
#define CONTRACT_INDEX QDRAW_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QDRAW
#define CONTRACT_STATE2_TYPE QDRAW2
#include "contracts/Qdraw.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define RL_CONTRACT_INDEX 16
#define CONTRACT_INDEX RL_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE RL
#define CONTRACT_STATE2_TYPE RL2
#include "contracts/RandomLottery.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QBOND_CONTRACT_INDEX 17
#define CONTRACT_INDEX QBOND_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QBOND
#define CONTRACT_STATE2_TYPE QBOND2
#include "contracts/QBond.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QIP_CONTRACT_INDEX 18
#define CONTRACT_INDEX QIP_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QIP
#define CONTRACT_STATE2_TYPE QIP2
#include "contracts/QIP.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QRAFFLE_CONTRACT_INDEX 19
#define CONTRACT_INDEX QRAFFLE_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QRAFFLE
#define CONTRACT_STATE2_TYPE QRAFFLE2
#include "contracts/QRaffle.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QRWA_CONTRACT_INDEX 20
#define CONTRACT_INDEX QRWA_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QRWA
#define CONTRACT_STATE2_TYPE QRWA2
#include "contracts/qRWA.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QRP_CONTRACT_INDEX 21
#define CONTRACT_INDEX QRP_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QRP
#define CONTRACT_STATE2_TYPE QRP2
#include "contracts/QReservePool.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QTF_CONTRACT_INDEX 22
#define CONTRACT_INDEX QTF_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QTF
#define CONTRACT_STATE2_TYPE QTF2
#include "contracts/QThirtyFour.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QDUEL_CONTRACT_INDEX 23
#define CONTRACT_INDEX QDUEL_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QDUEL
#define CONTRACT_STATE2_TYPE QDUEL2
#include "contracts/QDuel.h"
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define QUGATE_CONTRACT_INDEX 24
#define CONTRACT_INDEX QUGATE_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE QUGATE
#define CONTRACT_STATE2_TYPE QUGATE2
#include "contracts/QuGate.h"
// new contracts should be added above this line
#ifdef INCLUDE_CONTRACT_TEST_EXAMPLES
// forward declaration, defined in qpi_spectrum_impl.h
static void setContractFeeReserve(unsigned int contractIndex, long long newValue);
constexpr unsigned short TESTEXA_CONTRACT_INDEX = (CONTRACT_INDEX + 1);
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define CONTRACT_INDEX TESTEXA_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE TESTEXA
#define CONTRACT_STATE2_TYPE TESTEXA2
#include "contracts/TestExampleA.h"
constexpr unsigned short TESTEXB_CONTRACT_INDEX = (CONTRACT_INDEX + 1);
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define CONTRACT_INDEX TESTEXB_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE TESTEXB
#define CONTRACT_STATE2_TYPE TESTEXB2
#include "contracts/TestExampleB.h"
constexpr unsigned short TESTEXC_CONTRACT_INDEX = (CONTRACT_INDEX + 1);
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define CONTRACT_INDEX TESTEXC_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE TESTEXC
#define CONTRACT_STATE2_TYPE TESTEXC2
#include "contracts/TestExampleC.h"
constexpr unsigned short TESTEXD_CONTRACT_INDEX = (CONTRACT_INDEX + 1);
#undef CONTRACT_INDEX
#undef CONTRACT_STATE_TYPE
#undef CONTRACT_STATE2_TYPE
#define CONTRACT_INDEX TESTEXD_CONTRACT_INDEX
#define CONTRACT_STATE_TYPE TESTEXD
#define CONTRACT_STATE2_TYPE TESTEXD2
#include "contracts/TestExampleD.h"
#endif
#define MAX_CONTRACT_ITERATION_DURATION 0 // In milliseconds, must be above 0; for now set to 0 to disable timeout, because a rollback mechanism needs to be implemented to properly handle timeout
#undef INITIALIZE
#undef BEGIN_EPOCH
#undef END_EPOCH
#undef BEGIN_TICK
#undef END_TICK
#undef PRE_RELEASE_SHARES
#undef PRE_ACQUIRE_SHARES
#undef POST_RELEASE_SHARES
#undef POST_ACQUIRE_SHARES
#undef POST_INCOMING_TRANSFER
#undef SET_SHAREHOLDER_PROPOSAL
#undef SET_SHAREHOLDER_VOTES
// The following are included after the contracts to keep their definitions and dependencies
// inaccessible for contracts
#include "qpi_collection_impl.h"
#include "qpi_trivial_impl.h"
#include "qpi_hash_map_impl.h"
#include "platform/global_var.h"
#include "network_messages/common_def.h"
struct Contract0State
{
long long contractFeeReserves[MAX_NUMBER_OF_CONTRACTS];
};
struct IPO
{
m256i publicKeys[NUMBER_OF_COMPUTORS];
long long prices[NUMBER_OF_COMPUTORS];
};
static_assert(sizeof(IPO) == 32 * NUMBER_OF_COMPUTORS + 8 * NUMBER_OF_COMPUTORS, "Something is wrong with the struct size.");
constexpr struct ContractDescription
{
char assetName[8];
// constructionEpoch needs to be set to after IPO (IPO is before construction)
unsigned short constructionEpoch, destructionEpoch;
unsigned long long stateSize;
} contractDescriptions[] = {
{"", 0, 0, sizeof(Contract0State)},
{"QX", 66, 10000, sizeof(QX)},
{"QTRY", 72, 10000, sizeof(QUOTTERY)},
{"RANDOM", 88, 10000, sizeof(IPO)},
{"QUTIL", 99, 10000, sizeof(QUTIL)},
{"MLM", 112, 10000, sizeof(IPO)},
{"GQMPROP", 123, 10000, sizeof(GQMPROP)},
{"SWATCH", 123, 10000, sizeof(IPO)},
{"CCF", 127, 10000, sizeof(CCF)}, // proposal in epoch 125, IPO in 126, construction and first use in 127
{"QEARN", 137, 10000, sizeof(QEARN)}, // proposal in epoch 135, IPO in 136, construction in 137 / first donation after END_EPOCH, first round in epoch 138
{"QVAULT", 138, 10000, sizeof(IPO)}, // proposal in epoch 136, IPO in 137, construction and first use in 138
{"MSVAULT", 149, 10000, sizeof(MSVAULT)}, // proposal in epoch 147, IPO in 148, construction and first use in 149
{"QBAY", 154, 10000, sizeof(QBAY)}, // proposal in epoch 152, IPO in 153, construction and first use in 154
{"QSWAP", 171, 10000, sizeof(QSWAP)}, // proposal in epoch 169, IPO in 170, construction and first use in 171
{"NOST", 172, 10000, sizeof(NOST)}, // proposal in epoch 170, IPO in 171, construction and first use in 172
{"QDRAW", 179, 10000, sizeof(QDRAW)}, // proposal in epoch 177, IPO in 178, construction and first use in 179
{"RL", 182, 10000, sizeof(RL)}, // proposal in epoch 180, IPO in 181, construction and first use in 182
{"QBOND", 182, 10000, sizeof(QBOND)}, // proposal in epoch 180, IPO in 181, construction and first use in 182
{"QIP", 189, 10000, sizeof(QIP)}, // proposal in epoch 187, IPO in 188, construction and first use in 189
{"QRAFFLE", 192, 10000, sizeof(QRAFFLE)}, // proposal in epoch 190, IPO in 191, construction and first use in 192
{"QRWA", 197, 10000, sizeof(QRWA)}, // proposal in epoch 195, IPO in 196, construction and first use in 197
{"QRP", 199, 10000, sizeof(IPO)}, // proposal in epoch 197, IPO in 198, construction and first use in 199
{"QTF", 199, 10000, sizeof(QTF)}, // proposal in epoch 197, IPO in 198, construction and first use in 199
{"QDUEL", 199, 10000, sizeof(QDUEL)}, // proposal in epoch 197, IPO in 198, construction and first use in 199
{"QUGATE", 0, 10000, sizeof(QUGATE)}, // TBD: proposal, IPO, and construction epochs
// new contracts should be added above this line
#ifdef INCLUDE_CONTRACT_TEST_EXAMPLES
{"TESTEXA", 138, 10000, sizeof(TESTEXA)},
{"TESTEXB", 138, 10000, sizeof(TESTEXB)},
{"TESTEXC", 138, 10000, sizeof(IPO)},
{"TESTEXD", 155, 10000, sizeof(IPO)},
#endif
};
constexpr unsigned int contractCount = sizeof(contractDescriptions) / sizeof(contractDescriptions[0]);
GLOBAL_VAR_DECL EXPAND_PROCEDURE contractExpandProcedures[contractCount];
// TODO: all below are filled very sparsely, so a better data structure could save almost all the memory
GLOBAL_VAR_DECL USER_FUNCTION contractUserFunctions[contractCount][65536];
GLOBAL_VAR_DECL unsigned short contractUserFunctionInputSizes[contractCount][65536];
GLOBAL_VAR_DECL unsigned short contractUserFunctionOutputSizes[contractCount][65536];
// This has been changed to unsigned short to avoid the misalignment issue happening in epochs 109 and 110,
// probably due to too high numbers in contractUserProcedureLocalsSizes causing stack buffer alloc to fail
// probably due to buffer overflow that is difficult to reproduce in test net
// TODO: change back to unsigned int
GLOBAL_VAR_DECL unsigned short contractUserFunctionLocalsSizes[contractCount][65536];
GLOBAL_VAR_DECL USER_PROCEDURE contractUserProcedures[contractCount][65536];
GLOBAL_VAR_DECL unsigned short contractUserProcedureInputSizes[contractCount][65536];
GLOBAL_VAR_DECL unsigned short contractUserProcedureOutputSizes[contractCount][65536];
// This has been changed to unsigned short to avoid the misalignment issue happening in epochs 109 and 110,
// probably due to too high numbers in contractUserProcedureLocalsSizes causing stack buffer alloc to fail
// probably due to buffer overflow that is difficult to reproduce in test net
// TODO: change back to unsigned int
GLOBAL_VAR_DECL unsigned short contractUserProcedureLocalsSizes[contractCount][65536];
enum SystemProcedureID
{
INITIALIZE = 0,
BEGIN_EPOCH,
END_EPOCH,
BEGIN_TICK,
END_TICK,
PRE_RELEASE_SHARES,
PRE_ACQUIRE_SHARES,
POST_RELEASE_SHARES,
POST_ACQUIRE_SHARES,
POST_INCOMING_TRANSFER,
SET_SHAREHOLDER_PROPOSAL,
SET_SHAREHOLDER_VOTES,
contractSystemProcedureCount,
};
enum OtherEntryPointIDs
{
// Used together with SystemProcedureID values, so there must be no overlap!
USER_PROCEDURE_CALL = contractSystemProcedureCount + 1,
USER_FUNCTION_CALL = contractSystemProcedureCount + 2,
REGISTER_USER_FUNCTIONS_AND_PROCEDURES_CALL = contractSystemProcedureCount + 3,
USER_PROCEDURE_NOTIFICATION_CALL = contractSystemProcedureCount + 4,
};
GLOBAL_VAR_DECL SYSTEM_PROCEDURE contractSystemProcedures[contractCount][contractSystemProcedureCount];
GLOBAL_VAR_DECL unsigned short contractSystemProcedureLocalsSizes[contractCount][contractSystemProcedureCount];
#define REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(contractName) { \
constexpr unsigned int contractIndex = contractName##_CONTRACT_INDEX; \
if (!contractName::__initializeEmpty) contractSystemProcedures[contractIndex][INITIALIZE] = (SYSTEM_PROCEDURE)contractName::__initialize;\
contractSystemProcedureLocalsSizes[contractIndex][INITIALIZE] = contractName::__initializeLocalsSize; \
if (!contractName::__beginEpochEmpty) contractSystemProcedures[contractIndex][BEGIN_EPOCH] = (SYSTEM_PROCEDURE)contractName::__beginEpoch;\
contractSystemProcedureLocalsSizes[contractIndex][BEGIN_EPOCH] = contractName::__beginEpochLocalsSize; \
if (!contractName::__endEpochEmpty) contractSystemProcedures[contractIndex][END_EPOCH] = (SYSTEM_PROCEDURE)contractName::__endEpoch;\
contractSystemProcedureLocalsSizes[contractIndex][END_EPOCH] = contractName::__endEpochLocalsSize; \
if (!contractName::__beginTickEmpty) contractSystemProcedures[contractIndex][BEGIN_TICK] = (SYSTEM_PROCEDURE)contractName::__beginTick;\
contractSystemProcedureLocalsSizes[contractIndex][BEGIN_TICK] = contractName::__beginTickLocalsSize; \
if (!contractName::__endTickEmpty) contractSystemProcedures[contractIndex][END_TICK] = (SYSTEM_PROCEDURE)contractName::__endTick;\
contractSystemProcedureLocalsSizes[contractIndex][END_TICK] = contractName::__endTickLocalsSize; \
if (!contractName::__preAcquireSharesEmpty) contractSystemProcedures[contractIndex][PRE_ACQUIRE_SHARES] = (SYSTEM_PROCEDURE)contractName::__preAcquireShares;\
contractSystemProcedureLocalsSizes[contractIndex][PRE_ACQUIRE_SHARES] = contractName::__preAcquireSharesLocalsSize; \
if (!contractName::__preReleaseSharesEmpty) contractSystemProcedures[contractIndex][PRE_RELEASE_SHARES] = (SYSTEM_PROCEDURE)contractName::__preReleaseShares;\
contractSystemProcedureLocalsSizes[contractIndex][PRE_RELEASE_SHARES] = contractName::__preReleaseSharesLocalsSize; \
if (!contractName::__postAcquireSharesEmpty) contractSystemProcedures[contractIndex][POST_ACQUIRE_SHARES] = (SYSTEM_PROCEDURE)contractName::__postAcquireShares;\
contractSystemProcedureLocalsSizes[contractIndex][POST_ACQUIRE_SHARES] = contractName::__postAcquireSharesLocalsSize; \
if (!contractName::__postReleaseSharesEmpty) contractSystemProcedures[contractIndex][POST_RELEASE_SHARES] = (SYSTEM_PROCEDURE)contractName::__postReleaseShares;\
contractSystemProcedureLocalsSizes[contractIndex][POST_RELEASE_SHARES] = contractName::__postReleaseSharesLocalsSize; \
if (!contractName::__postIncomingTransferEmpty) contractSystemProcedures[contractIndex][POST_INCOMING_TRANSFER] = (SYSTEM_PROCEDURE)contractName::__postIncomingTransfer;\
contractSystemProcedureLocalsSizes[contractIndex][POST_INCOMING_TRANSFER] = contractName::__postIncomingTransferLocalsSize; \
if (!contractName::__setShareholderProposalEmpty) contractSystemProcedures[contractIndex][SET_SHAREHOLDER_PROPOSAL] = (SYSTEM_PROCEDURE)contractName::__setShareholderProposal;\
contractSystemProcedureLocalsSizes[contractIndex][SET_SHAREHOLDER_PROPOSAL] = contractName::__setShareholderProposalLocalsSize; \
if (!contractName::__setShareholderVotesEmpty) contractSystemProcedures[contractIndex][SET_SHAREHOLDER_VOTES] = (SYSTEM_PROCEDURE)contractName::__setShareholderVotes;\
contractSystemProcedureLocalsSizes[contractIndex][SET_SHAREHOLDER_VOTES] = contractName::__setShareholderVotesLocalsSize; \
if (!contractName::__expandEmpty) contractExpandProcedures[contractIndex] = (EXPAND_PROCEDURE)contractName::__expand;\
QpiContextForInit qpi(contractIndex); \
contractName::__registerUserFunctionsAndProcedures(qpi); \
static_assert(sizeof(contractName) <= MAX_CONTRACT_STATE_SIZE, "Size of contract state " #contractName " is too large!"); \
}
static void initializeContracts()
{
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QX);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QUOTTERY);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(RANDOM);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QUTIL);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(MLM);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(GQMPROP);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(SWATCH);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(CCF);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QEARN);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QVAULT);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(MSVAULT);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QBAY);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QSWAP);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(NOST);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QDRAW);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(RL);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QBOND);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QIP);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QRAFFLE);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QRWA);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QRP);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QTF);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QDUEL);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(QUGATE);
// new contracts should be added above this line
#ifdef INCLUDE_CONTRACT_TEST_EXAMPLES
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(TESTEXA);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(TESTEXB);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(TESTEXC);
REGISTER_CONTRACT_FUNCTIONS_AND_PROCEDURES(TESTEXD);
// fill execution fee reserves for test contracts
setContractFeeReserve(TESTEXA_CONTRACT_INDEX, 100000000000);
setContractFeeReserve(TESTEXB_CONTRACT_INDEX, 100000000000);
setContractFeeReserve(TESTEXC_CONTRACT_INDEX, 100000000000);
setContractFeeReserve(TESTEXD_CONTRACT_INDEX, 100000000000);
#endif
}
// Class for registering and looking up user procedures independently of input type, for example for notifications
class UserProcedureRegistry
{
public:
struct UserProcedureData
{
USER_PROCEDURE procedure;
unsigned int contractIndex;
unsigned int localsSize;
unsigned short inputSize;
unsigned short outputSize;
};
void init()
{
setMemory(*this, 0);
}
bool add(unsigned int procedureId, const UserProcedureData& data)
{
const unsigned int cnt = (unsigned int)idToIndex.population();
if (cnt >= idToIndex.capacity())
return false;
copyMemory(userProcData[cnt], data);
idToIndex.set(procedureId, cnt);
return true;
}
const UserProcedureData* get(unsigned int procedureId) const
{
unsigned int idx;
if (!idToIndex.get(procedureId, idx))
return nullptr;
return userProcData + idx;
}
protected:
UserProcedureData userProcData[MAX_CONTRACT_PROCEDURES_REGISTERED];
QPI::HashMap<unsigned int, unsigned int, MAX_CONTRACT_PROCEDURES_REGISTERED> idToIndex;
};
// For registering and looking up user procedures independently of input type (for notifications), initialized by initContractExec()
GLOBAL_VAR_DECL UserProcedureRegistry* userProcedureRegistry GLOBAL_VAR_INIT(nullptr);