1 /******************************************************************************
2 * Copyright © 2014-2018 The SuperNET Developers. *
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. *
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 *
12 * Removal or modification of this copyright notice is prohibited. *
14 ******************************************************************************/
17 #include <cryptoconditions.h>
19 #include "primitives/block.h"
20 #include "primitives/transaction.h"
21 #include "script/cc.h"
24 #include "cc/CCinclude.h"
28 #include "crosschain.h"
32 struct CCcontract_info CCinfos[0x100];
33 extern pthread_mutex_t KOMODO_CC_mutex;
35 bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
38 pthread_mutex_lock(&KOMODO_CC_mutex);
39 bool out = eval->Dispatch(cond, tx, nIn);
40 pthread_mutex_unlock(&KOMODO_CC_mutex);
41 //fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
42 assert(eval->state.IsValid() == out);
44 if (eval->state.IsValid()) return true;
46 std::string lvl = eval->state.IsInvalid() ? "Invalid" : "Error!";
47 fprintf(stderr, "CC Eval %s %s: %s spending tx %s\n",
48 EvalToStr(cond->code[0]).data(),
50 eval->state.GetRejectReason().data(),
51 tx.vin[nIn].prevout.hash.GetHex().data());
52 if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data());
58 * Test the validity of an Eval node
60 bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
62 struct CCcontract_info *cp;
63 if (cond->codeLength == 0)
64 return Invalid("empty-eval");
66 uint8_t ecode = cond->code[0];
67 cp = &CCinfos[(int32_t)ecode];
68 if ( cp->didinit == 0 )
73 std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
76 case EVAL_IMPORTPAYOUT:
77 //return ImportPayout(vparams, txTo, nIn);
81 //return ImportCoin(vparams, txTo, nIn);
85 // only support coinbase guard for now
86 if (ecode == EVAL_STAKEGUARD)
87 return(ProcessCC(cp,this, vparams, txTo, nIn));
90 return Invalid("invalid-code, dont forget to add EVAL_NEWCC to Eval::Dispatch");
94 bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const
101 bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
103 // there is a LOCK(cs_main) in the normal GetTransaction(), which leads to deadlocks
104 //bool fAllowSlow = false; // Don't allow slow
105 //return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
106 return myGetTransaction(hash, txOut,hashBlock);
110 bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const
113 if (!GetTxUnconfirmed(hash, txOut, hashBlock))
115 if (hashBlock.IsNull() || !GetBlock(hashBlock, block))
121 unsigned int Eval::GetCurrentHeight() const
123 return chainActive.Height();
126 bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
128 auto r = mapBlockIndex.find(hash);
129 if (r != mapBlockIndex.end()) {
130 blockIdx = *r->second;
133 fprintf(stderr, "CC Eval Error: Can't get block from index\n");
137 extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
140 int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
142 return komodo_notaries(pubkeys, height, timestamp);
146 bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
148 if (tx.vin.size() < 11) return false;
150 uint8_t seenNotaries[64] = {0};
151 uint8_t notaries[64][33];
152 int nNotaries = GetNotaries(notaries, height, timestamp);
154 BOOST_FOREACH(const CTxIn &txIn, tx.vin)
159 if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false;
160 if (tx.vout.size() < txIn.prevout.n) return false;
161 CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
162 if (spk.size() != 35) return false;
163 std::vector<unsigned char> scriptVec = std::vector<unsigned char>(spk.begin(),spk.end());
164 const unsigned char *pk = scriptVec.data();
165 if (pk++[0] != 33) return false;
166 if (pk[33] != OP_CHECKSIG) return false;
168 // Check it's a notary
169 for (int i=0; i<nNotaries; i++) {
170 if (!seenNotaries[i]) {
171 if (memcmp(pk, notaries[i], 33) == 0) {
186 * Get MoM from a notarisation tx hash (on KMD)
188 bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
190 CTransaction notarisationTx;
192 if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false;
193 if (!CheckNotaryInputs(notarisationTx, block.GetHeight(), block.nTime)) return false;
194 if (!ParseNotarisationOpReturn(notarisationTx, data)) return false;
199 * Get MoMoM corresponding to a notarisation tx hash (on assetchain)
201 bool Eval::GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const
203 std::pair<uint256,NotarisationData> out;
204 if (!GetNextBacknotarisation(kmdNotarisationHash, out)) return false;
205 momom = out.second.MoMoM;
210 uint32_t Eval::GetAssetchainsCC() const
212 return ASSETCHAINS_CC;
216 std::string Eval::GetAssetchainsSymbol() const
218 return std::string(ASSETCHAINS_SYMBOL);
223 * Notarisation data, ie, OP_RETURN payload in notarisation transactions
225 bool ParseNotarisationOpReturn(const CTransaction &tx, NotarisationData &data)
227 if (tx.vout.size() < 2) return false;
228 std::vector<unsigned char> vdata;
229 if (!GetOpReturnData(tx.vout[1].scriptPubKey, vdata)) return false;
230 bool out = E_UNMARSHAL(vdata, ss >> data);
238 std::string EvalToStr(EvalCode c)
240 FOREACH_EVAL(EVAL_GENERATE_STRING);
242 sprintf(s, "0x%x", c);
243 return std::string(s);
248 uint256 SafeCheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
252 for (auto it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
256 // non canonical. hash may be equal to node but never on the right.
259 hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
262 hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
269 uint256 GetMerkleRoot(const std::vector<uint256>& vLeaves)
272 std::vector<uint256> vMerkleTree;
273 return BuildMerkleTree(&fMutated, vLeaves, vMerkleTree);