]>
Commit | Line | Data |
---|---|---|
f345b953 | 1 | /****************************************************************************** |
2 | * Copyright © 2014-2018 The SuperNET Developers. * | |
3 | * * | |
4 | * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * | |
5 | * the top-level directory of this distribution for the individual copyright * | |
6 | * holder information and the developer policies on copyright and licensing. * | |
7 | * * | |
8 | * Unless otherwise agreed in a custom licensing agreement, no part of the * | |
9 | * SuperNET software, including this file may be copied, modified, propagated * | |
10 | * or distributed except according to the terms contained in the LICENSE file * | |
11 | * * | |
12 | * Removal or modification of this copyright notice is prohibited. * | |
13 | * * | |
14 | ******************************************************************************/ | |
15 | ||
2c8d8268 SS |
16 | #ifndef CC_EVAL_H |
17 | #define CC_EVAL_H | |
18 | ||
561f3e18 SS |
19 | #include <cryptoconditions.h> |
20 | ||
20c3ac51 | 21 | #include "cc/utils.h" |
561f3e18 SS |
22 | #include "chain.h" |
23 | #include "streams.h" | |
24 | #include "version.h" | |
25 | #include "consensus/validation.h" | |
2c8d8268 SS |
26 | #include "primitives/transaction.h" |
27 | ||
072dba5f | 28 | #define KOMODO_FIRSTFUNGIBLEID 100 |
2c8d8268 | 29 | |
39c9911e SS |
30 | /* |
31 | * Eval codes | |
32 | * | |
33 | * Add to below macro to generate new code. | |
34 | * | |
35 | * If at some point a new interpretation model is introduced, | |
36 | * there should be a code identifying it. For example, | |
37 | * a possible code is EVAL_BITCOIN_SCRIPT, where the entire binary | |
38 | * after the code is interpreted as a bitcoin script. | |
39 | */ | |
0cb91a8d | 40 | #define FOREACH_EVAL(EVAL) \ |
0d7fed99 | 41 | EVAL(EVAL_NONE, 0x0) \ |
ca4a5f26 | 42 | EVAL(EVAL_STAKEGUARD, 0x1) \ |
b2a98c42 MT |
43 | EVAL(EVAL_PBAASDEFINITION, 0x2) \ |
44 | EVAL(EVAL_SERVICEREWARD, 0x3) \ | |
45 | EVAL(EVAL_EARNEDNOTARIZATION, 0x4) \ | |
46 | EVAL(EVAL_ACCEPTEDNOTARIZATION, 0x5) \ | |
47 | EVAL(EVAL_FINALIZENOTARIZATION, 0x6) \ | |
41f170fd | 48 | EVAL(EVAL_CURRENCYSTATE, 0x7) \ |
989b1de1 | 49 | EVAL(EVAL_RESERVE_TRANSFER, 0x8) \ |
a6e612cc MT |
50 | EVAL(EVAL_RESERVE_OUTPUT, 0x9) \ |
51 | EVAL(EVAL_RESERVE_EXCHANGE, 0xa) \ | |
989b1de1 MT |
52 | EVAL(EVAL_RESERVE_DEPOSIT, 0xb) \ |
53 | EVAL(EVAL_CROSSCHAIN_EXPORT, 0xc) \ | |
54 | EVAL(EVAL_CROSSCHAIN_IMPORT, 0xd) \ | |
f0d54147 | 55 | EVAL(EVAL_IDENTITY_PRIMARY, 0xe) \ |
56 | EVAL(EVAL_IDENTITY_REVOKE, 0xf) \ | |
57 | EVAL(EVAL_IDENTITY_RECOVER, 0x10) \ | |
b7c685b8 | 58 | EVAL(EVAL_IDENTITY_COMMITMENT, 0x11) \ |
59 | EVAL(EVAL_IDENTITY_RESERVATION, 0x12) \ | |
0cb91a8d | 60 | EVAL(EVAL_IMPORTPAYOUT, 0xe1) \ |
4802c859 MT |
61 | EVAL(EVAL_IMPORTCOIN, 0xe2) \ |
62 | EVAL(EVAL_ASSETS, 0xe3) \ | |
194ad5b8 | 63 | EVAL(EVAL_FAUCET, 0xe4) \ |
2fcf7a42 | 64 | EVAL(EVAL_REWARDS, 0xe5) \ |
69829385 | 65 | EVAL(EVAL_DICE, 0xe6) \ |
7137a022 | 66 | EVAL(EVAL_FSM, 0xe7) \ |
69829385 | 67 | EVAL(EVAL_AUCTION, 0xe8) \ |
da629dfe | 68 | EVAL(EVAL_LOTTO, 0xe9) \ |
69 | EVAL(EVAL_MOFN, 0xea) \ | |
70 | EVAL(EVAL_CHANNELS, 0xeb) \ | |
71 | EVAL(EVAL_ORACLES, 0xec) \ | |
72 | EVAL(EVAL_PRICES, 0xed) \ | |
73 | EVAL(EVAL_PEGS, 0xee) \ | |
74 | EVAL(EVAL_TRIGGERS, 0xef) \ | |
75 | EVAL(EVAL_PAYMENTS, 0xf0) \ | |
76 | EVAL(EVAL_GATEWAYS, 0xf1) | |
0cb91a8d | 77 | |
39c9911e SS |
78 | |
79 | typedef uint8_t EvalCode; | |
80 | ||
81 | ||
561f3e18 | 82 | class AppVM; |
9bf132a5 | 83 | class NotarisationData; |
561f3e18 SS |
84 | |
85 | ||
86 | class Eval | |
87 | { | |
88 | public: | |
89 | CValidationState state; | |
90 | ||
91 | bool Invalid(std::string s) { return state.Invalid(false, 0, s); } | |
92 | bool Error(std::string s) { return state.Error(s); } | |
93 | bool Valid() { return true; } | |
94 | ||
95 | /* | |
96 | * Test validity of a CC_Eval node | |
97 | */ | |
4ecaf167 | 98 | virtual bool Dispatch(const CC *cond, const CTransaction &tx, unsigned int nIn, bool fulfilled); |
561f3e18 SS |
99 | |
100 | /* | |
101 | * Dispute a payout using a VM | |
102 | */ | |
39c9911e | 103 | bool DisputePayout(AppVM &vm, std::vector<uint8_t> params, const CTransaction &disputeTx, unsigned int nIn); |
561f3e18 SS |
104 | |
105 | /* | |
106 | * Test an ImportPayout CC Eval condition | |
107 | */ | |
39c9911e | 108 | bool ImportPayout(std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn); |
561f3e18 | 109 | |
0cb91a8d SS |
110 | /* |
111 | * Import coin from another chain with same symbol | |
112 | */ | |
113 | bool ImportCoin(std::vector<uint8_t> params, const CTransaction &importTx, unsigned int nIn); | |
114 | ||
561f3e18 SS |
115 | /* |
116 | * IO functions | |
117 | */ | |
47296322 SS |
118 | virtual bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const; |
119 | virtual bool GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const; | |
561f3e18 | 120 | virtual unsigned int GetCurrentHeight() const; |
47296322 | 121 | virtual bool GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const; |
561f3e18 | 122 | virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const; |
9bf132a5 SS |
123 | virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const; |
124 | virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const; | |
e4f943d8 | 125 | virtual bool GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const; |
561f3e18 | 126 | virtual bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const; |
0df96a2f SS |
127 | virtual uint32_t GetAssetchainsCC() const; |
128 | virtual std::string GetAssetchainsSymbol() const; | |
561f3e18 SS |
129 | }; |
130 | ||
131 | ||
20c3ac51 SS |
132 | extern Eval* EVAL_TEST; |
133 | ||
134 | ||
135 | /* | |
136 | * Get a pointer to an Eval to use | |
137 | */ | |
138 | typedef std::unique_ptr<Eval,void(*)(Eval*)> EvalRef_; | |
139 | class EvalRef : public EvalRef_ | |
140 | { | |
141 | public: | |
142 | EvalRef() : EvalRef_( | |
143 | EVAL_TEST ? EVAL_TEST : new Eval(), | |
144 | [](Eval* e){if (e!=EVAL_TEST) delete e;}) { } | |
145 | }; | |
146 | ||
147 | ||
148 | ||
4ecaf167 | 149 | bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn, bool fulfilled); |
561f3e18 | 150 | |
2c8d8268 | 151 | |
9ef101bc SS |
152 | /* |
153 | * Virtual machine to use in the case of on-chain app evaluation | |
154 | */ | |
155 | class AppVM | |
156 | { | |
157 | public: | |
158 | /* | |
159 | * in: header - paramters agreed upon by all players | |
160 | * in: body - gamestate | |
161 | * out: length - length of game (longest wins) | |
162 | * out: payments - vector of CTxOut, always deterministically sorted. | |
163 | */ | |
164 | virtual std::pair<int,std::vector<CTxOut>> | |
165 | evaluate(std::vector<unsigned char> header, std::vector<unsigned char> body) = 0; | |
166 | }; | |
167 | ||
20c3ac51 SS |
168 | |
169 | extern char ASSETCHAINS_SYMBOL[65]; | |
170 | ||
171 | ||
9ef101bc | 172 | /* |
20c3ac51 | 173 | * Data from notarisation OP_RETURN from chain being notarised |
9ef101bc | 174 | */ |
20c3ac51 SS |
175 | class NotarisationData |
176 | { | |
9bf132a5 | 177 | public: |
06c960d2 | 178 | int IsBackNotarisation = 0; |
fe727b9d SS |
179 | uint256 blockHash = uint256(); |
180 | uint32_t height = 0; | |
181 | uint256 txHash = uint256(); | |
7efaea18 | 182 | char symbol[64]; |
fe727b9d SS |
183 | uint256 MoM = uint256(); |
184 | uint16_t MoMDepth = 0; | |
185 | uint16_t ccId = 0; | |
186 | uint256 MoMoM = uint256(); | |
187 | uint32_t MoMoMDepth = 0; | |
9bf132a5 | 188 | |
7efaea18 SS |
189 | NotarisationData(int IsBack=2) : IsBackNotarisation(IsBack) { |
190 | symbol[0] = '\0'; | |
191 | } | |
20c3ac51 SS |
192 | |
193 | ADD_SERIALIZE_METHODS; | |
194 | ||
195 | template <typename Stream, typename Operation> | |
9feb4b9e | 196 | inline void SerializationOp(Stream& s, Operation ser_action) { |
a748b1a2 SS |
197 | |
198 | bool IsBack = IsBackNotarisation; | |
3fdb3782 | 199 | if (2 == IsBackNotarisation) IsBack = DetectBackNotarisation(s, ser_action); |
a748b1a2 | 200 | |
20c3ac51 SS |
201 | READWRITE(blockHash); |
202 | READWRITE(height); | |
a748b1a2 | 203 | if (IsBack) |
20c3ac51 SS |
204 | READWRITE(txHash); |
205 | SerSymbol(s, ser_action); | |
a748b1a2 | 206 | if (s.size() == 0) return; |
20c3ac51 SS |
207 | READWRITE(MoM); |
208 | READWRITE(MoMDepth); | |
20c3ac51 | 209 | READWRITE(ccId); |
91d92922 | 210 | if (s.size() == 0) return; |
a748b1a2 | 211 | if (IsBack) { |
20c3ac51 SS |
212 | READWRITE(MoMoM); |
213 | READWRITE(MoMoMDepth); | |
214 | } | |
215 | } | |
216 | ||
217 | template <typename Stream> | |
218 | void SerSymbol(Stream& s, CSerActionSerialize act) | |
219 | { | |
220 | s.write(symbol, strlen(symbol)+1); | |
221 | } | |
222 | ||
223 | template <typename Stream> | |
224 | void SerSymbol(Stream& s, CSerActionUnserialize act) | |
225 | { | |
7efaea18 SS |
226 | size_t readlen = std::min(sizeof(symbol), s.size()); |
227 | char *nullPos = (char*) memchr(&s[0], 0, readlen); | |
20c3ac51 SS |
228 | if (!nullPos) |
229 | throw std::ios_base::failure("couldn't parse symbol"); | |
230 | s.read(symbol, nullPos-&s[0]+1); | |
231 | } | |
a748b1a2 SS |
232 | |
233 | template <typename Stream> | |
3fdb3782 | 234 | bool DetectBackNotarisation(Stream& s, CSerActionUnserialize act) |
a748b1a2 SS |
235 | { |
236 | if (ASSETCHAINS_SYMBOL[0]) return 1; | |
3fdb3782 SS |
237 | if (s.size() >= 72) { |
238 | if (strcmp("BTC", &s[68]) == 0) return 1; | |
239 | if (strcmp("KMD", &s[68]) == 0) return 1; | |
240 | } | |
a748b1a2 SS |
241 | return 0; |
242 | } | |
243 | ||
244 | template <typename Stream> | |
3fdb3782 | 245 | bool DetectBackNotarisation(Stream& s, CSerActionSerialize act) |
a748b1a2 SS |
246 | { |
247 | return !txHash.IsNull(); | |
248 | } | |
9bf132a5 | 249 | }; |
561f3e18 SS |
250 | |
251 | ||
20c3ac51 SS |
252 | bool ParseNotarisationOpReturn(const CTransaction &tx, NotarisationData &data); |
253 | ||
254 | ||
39c9911e SS |
255 | /* |
256 | * Eval code utilities. | |
257 | */ | |
258 | #define EVAL_GENERATE_DEF(L,I) const uint8_t L = I; | |
259 | #define EVAL_GENERATE_STRING(L,I) if (c == I) return #L; | |
260 | ||
261 | FOREACH_EVAL(EVAL_GENERATE_DEF); | |
262 | ||
263 | std::string EvalToStr(EvalCode c); | |
264 | ||
265 | ||
0cb91a8d SS |
266 | /* |
267 | * Merkle stuff | |
268 | */ | |
269 | uint256 SafeCheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); | |
270 | ||
271 | ||
272 | class MerkleBranch | |
273 | { | |
274 | public: | |
275 | int nIndex; | |
276 | std::vector<uint256> branch; | |
277 | ||
278 | MerkleBranch() {} | |
279 | MerkleBranch(int i, std::vector<uint256> b) : nIndex(i), branch(b) {} | |
280 | uint256 Exec(uint256 hash) const { return SafeCheckMerkleBranch(hash, branch, nIndex); } | |
281 | ||
20c3ac51 SS |
282 | MerkleBranch& operator<<(MerkleBranch append) |
283 | { | |
284 | nIndex += append.nIndex << branch.size(); | |
285 | branch.insert(branch.end(), append.branch.begin(), append.branch.end()); | |
286 | return *this; | |
287 | } | |
288 | ||
0cb91a8d SS |
289 | ADD_SERIALIZE_METHODS; |
290 | ||
291 | template <typename Stream, typename Operation> | |
9feb4b9e | 292 | inline void SerializationOp(Stream& s, Operation ser_action) { |
0cb91a8d SS |
293 | READWRITE(VARINT(nIndex)); |
294 | READWRITE(branch); | |
295 | } | |
296 | }; | |
297 | ||
298 | ||
e4f943d8 SS |
299 | typedef std::pair<uint256,MerkleBranch> TxProof; |
300 | ||
bbf91faa | 301 | bool DefaultCCContextualPreCheck(const CTransaction &tx, int32_t outNum, CValidationState &state, uint32_t height); |
20c3ac51 | 302 | uint256 GetMerkleRoot(const std::vector<uint256>& vLeaves); |
b6461360 | 303 | struct CCcontract_info *CCinit(struct CCcontract_info *cp,uint8_t evalcode); |
4ecaf167 | 304 | bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> paramsNull, const CTransaction &tx, unsigned int nIn, bool fulfilled); |
20c3ac51 SS |
305 | |
306 | ||
2c8d8268 | 307 | #endif /* CC_EVAL_H */ |