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