]> Git Repo - VerusCoin.git/blame - src/cc/eval.cpp
Sync last changes before testnet fork to repo
[VerusCoin.git] / src / cc / eval.cpp
CommitLineData
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
561f3e18
SS
16#include <assert.h>
17#include <cryptoconditions.h>
18
20c3ac51 19#include "primitives/block.h"
2c8d8268 20#include "primitives/transaction.h"
8a8e10f0 21#include "script/cc.h"
2c8d8268 22#include "cc/eval.h"
20c3ac51 23#include "cc/utils.h"
6d450023 24#include "cc/CCinclude.h"
561f3e18
SS
25#include "main.h"
26#include "chain.h"
aa9eec45 27#include "core_io.h"
0ffacf04 28#include "crosschain.h"
561f3e18
SS
29
30
31Eval* EVAL_TEST = 0;
287efad4 32struct CCcontract_info CCinfos[0x100];
63600b1d 33extern pthread_mutex_t KOMODO_CC_mutex;
561f3e18
SS
34
35bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
36{
20c3ac51 37 EvalRef eval;
63600b1d 38 pthread_mutex_lock(&KOMODO_CC_mutex);
561f3e18 39 bool out = eval->Dispatch(cond, tx, nIn);
63600b1d 40 pthread_mutex_unlock(&KOMODO_CC_mutex);
1f5f9d29 41 //fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
561f3e18
SS
42 assert(eval->state.IsValid() == out);
43
44 if (eval->state.IsValid()) return true;
45
46 std::string lvl = eval->state.IsInvalid() ? "Invalid" : "Error!";
39c9911e
SS
47 fprintf(stderr, "CC Eval %s %s: %s spending tx %s\n",
48 EvalToStr(cond->code[0]).data(),
49 lvl.data(),
50 eval->state.GetRejectReason().data(),
51 tx.vin[nIn].prevout.hash.GetHex().data());
aa9eec45 52 if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data());
561f3e18
SS
53 return false;
54}
2c8d8268
SS
55
56
57/*
58 * Test the validity of an Eval node
59 */
561f3e18 60bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
2c8d8268 61{
287efad4 62 struct CCcontract_info *cp;
39c9911e
SS
63 if (cond->codeLength == 0)
64 return Invalid("empty-eval");
2c8d8268 65
39c9911e 66 uint8_t ecode = cond->code[0];
287efad4 67 cp = &CCinfos[(int32_t)ecode];
68 if ( cp->didinit == 0 )
69 {
70 CCinit(cp,ecode);
71 cp->didinit = 1;
72 }
39c9911e 73 std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
44a9fd7c 74 switch ( ecode )
75 {
ef32da96
MT
76 case EVAL_PBAASDEFINITION:
77 case EVAL_SERVICEREWARD:
78 case EVAL_EARNEDNOTARIZATION:
79 case EVAL_ACCEPTEDNOTARIZATION:
80 case EVAL_FINALIZENOTARIZATION:
a6e612cc 81 case EVAL_RESERVE_OUTPUT:
e87527cf
MT
82 case EVAL_CROSSCHAIN_EXPORT:
83 case EVAL_CROSSCHAIN_IMPORT:
84 case EVAL_INSTANTSPEND:
a6e612cc 85 case EVAL_RESERVE_INPUT:
e87527cf
MT
86 if (!chainActive.LastTip() || CConstVerusSolutionVector::activationHeight.ActiveVersion(chainActive.LastTip()->GetHeight()) < CActivationHeight::SOLUTION_VERUSV3)
87 {
88 // if chain is not able to process this yet, don't drop through to do so
89 break;
90 }
91
92 case EVAL_STAKEGUARD:
b2a98c42
MT
93 return(ProcessCC(cp,this, vparams, txTo, nIn));
94 break;
95
44a9fd7c 96 case EVAL_IMPORTPAYOUT:
8a727a26 97 //return ImportPayout(vparams, txTo, nIn);
44a9fd7c 98 break;
99
100 case EVAL_IMPORTCOIN:
8a727a26 101 //return ImportCoin(vparams, txTo, nIn);
44a9fd7c 102 break;
0cb91a8d 103 }
216f23be 104 return Invalid("invalid-code, dont forget to add EVAL_NEWCC to Eval::Dispatch");
2c8d8268 105}
9ef101bc
SS
106
107
47296322 108bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const
9ef101bc 109{
561f3e18 110 // NOT IMPLEMENTED
9ef101bc
SS
111 return false;
112}
113
114
47296322 115bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
561f3e18 116{
02c68a7b 117 // there is a LOCK(cs_main) in the normal GetTransaction(), which leads to deadlocks
fc40b06c 118 //bool fAllowSlow = false; // Don't allow slow
119 //return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
21f17b88 120 return myGetTransaction(hash, txOut,hashBlock);
561f3e18
SS
121}
122
123
47296322
SS
124bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const
125{
126 uint256 hashBlock;
127 if (!GetTxUnconfirmed(hash, txOut, hashBlock))
128 return false;
129 if (hashBlock.IsNull() || !GetBlock(hashBlock, block))
130 return false;
131 return true;
132}
133
134
561f3e18
SS
135unsigned int Eval::GetCurrentHeight() const
136{
137 return chainActive.Height();
138}
139
561f3e18 140bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
9ef101bc 141{
561f3e18
SS
142 auto r = mapBlockIndex.find(hash);
143 if (r != mapBlockIndex.end()) {
144 blockIdx = *r->second;
145 return true;
146 }
47296322 147 fprintf(stderr, "CC Eval Error: Can't get block from index\n");
9ef101bc
SS
148 return false;
149}
150
561f3e18
SS
151extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
152
153
9bf132a5
SS
154int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
155{
156 return komodo_notaries(pubkeys, height, timestamp);
157}
158
159
561f3e18
SS
160bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
161{
162 if (tx.vin.size() < 11) return false;
163
9bf132a5 164 uint8_t seenNotaries[64] = {0};
561f3e18 165 uint8_t notaries[64][33];
9bf132a5 166 int nNotaries = GetNotaries(notaries, height, timestamp);
561f3e18
SS
167
168 BOOST_FOREACH(const CTxIn &txIn, tx.vin)
169 {
170 // Get notary pubkey
171 CTransaction tx;
172 uint256 hashBlock;
47296322 173 if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false;
561f3e18 174 if (tx.vout.size() < txIn.prevout.n) return false;
9bf132a5
SS
175 CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
176 if (spk.size() != 35) return false;
9feb4b9e 177 std::vector<unsigned char> scriptVec = std::vector<unsigned char>(spk.begin(),spk.end());
178 const unsigned char *pk = scriptVec.data();
9bf132a5
SS
179 if (pk++[0] != 33) return false;
180 if (pk[33] != OP_CHECKSIG) return false;
561f3e18
SS
181
182 // Check it's a notary
183 for (int i=0; i<nNotaries; i++) {
184 if (!seenNotaries[i]) {
185 if (memcmp(pk, notaries[i], 33) == 0) {
186 seenNotaries[i] = 1;
187 goto found;
188 }
189 }
190 }
191 return false;
192 found:;
193 }
9bf132a5
SS
194
195 return true;
196}
197
198
39c9911e 199/*
e4f943d8 200 * Get MoM from a notarisation tx hash (on KMD)
39c9911e
SS
201 */
202bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
203{
204 CTransaction notarisationTx;
205 CBlockIndex block;
206 if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false;
4b729ec5 207 if (!CheckNotaryInputs(notarisationTx, block.GetHeight(), block.nTime)) return false;
20c3ac51 208 if (!ParseNotarisationOpReturn(notarisationTx, data)) return false;
39c9911e
SS
209 return true;
210}
211
e4f943d8
SS
212/*
213 * Get MoMoM corresponding to a notarisation tx hash (on assetchain)
214 */
215bool Eval::GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const
0cb91a8d 216{
0ffacf04
SS
217 std::pair<uint256,NotarisationData> out;
218 if (!GetNextBacknotarisation(kmdNotarisationHash, out)) return false;
219 momom = out.second.MoMoM;
220 return true;
0df96a2f
SS
221}
222
223
224uint32_t Eval::GetAssetchainsCC() const
225{
226 return ASSETCHAINS_CC;
227}
228
229
230std::string Eval::GetAssetchainsSymbol() const
231{
232 return std::string(ASSETCHAINS_SYMBOL);
0cb91a8d
SS
233}
234
56cf273f 235
39c9911e
SS
236/*
237 * Notarisation data, ie, OP_RETURN payload in notarisation transactions
238 */
20c3ac51 239bool ParseNotarisationOpReturn(const CTransaction &tx, NotarisationData &data)
9bf132a5 240{
20c3ac51 241 if (tx.vout.size() < 2) return false;
9bf132a5 242 std::vector<unsigned char> vdata;
20c3ac51
SS
243 if (!GetOpReturnData(tx.vout[1].scriptPubKey, vdata)) return false;
244 bool out = E_UNMARSHAL(vdata, ss >> data);
245 return out;
561f3e18
SS
246}
247
248
249/*
39c9911e 250 * Misc
561f3e18 251 */
39c9911e 252std::string EvalToStr(EvalCode c)
561f3e18 253{
39c9911e
SS
254 FOREACH_EVAL(EVAL_GENERATE_STRING);
255 char s[10];
256 sprintf(s, "0x%x", c);
257 return std::string(s);
0cb91a8d
SS
258
259}
260
261
262uint256 SafeCheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
263{
264 if (nIndex == -1)
265 return uint256();
266 for (auto it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
267 {
268 if (nIndex & 1) {
269 if (*it == hash) {
270 // non canonical. hash may be equal to node but never on the right.
271 return uint256();
272 }
273 hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
274 }
275 else
276 hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
277 nIndex >>= 1;
278 }
279 return hash;
561f3e18 280}
20c3ac51
SS
281
282
283uint256 GetMerkleRoot(const std::vector<uint256>& vLeaves)
284{
285 bool fMutated;
286 std::vector<uint256> vMerkleTree;
287 return BuildMerkleTree(&fMutated, vLeaves, vMerkleTree);
288}
This page took 0.191892 seconds and 4 git commands to generate.