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