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