2 #include <cryptoconditions.h>
4 #include "primitives/transaction.h"
15 bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
18 Eval *eval = EVAL_TEST;
19 if (!eval) eval = &eval_;
21 bool out = eval->Dispatch(cond, tx, nIn);
22 assert(eval->state.IsValid() == out);
24 if (eval->state.IsValid()) return true;
26 std::string lvl = eval->state.IsInvalid() ? "Invalid" : "Error!";
27 fprintf(stderr, "CC Eval %s %s: %s spending tx %s\n",
28 EvalToStr(cond->code[0]).data(),
30 eval->state.GetRejectReason().data(),
31 tx.vin[nIn].prevout.hash.GetHex().data());
32 if (eval->state.IsError()) fprintf(stderr, "Culprit: %s\n", EncodeHexTx(tx).data());
38 * Test the validity of an Eval node
40 bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
42 if (cond->codeLength == 0)
43 return Invalid("empty-eval");
45 uint8_t ecode = cond->code[0];
46 std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
48 if (ecode == EVAL_IMPORTPAYOUT) {
49 return ImportPayout(vparams, txTo, nIn);
52 return Invalid("invalid-code");
56 bool Eval::GetSpendsConfirmed(uint256 hash, std::vector<CTransaction> &spends) const
63 bool Eval::GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const
65 bool fAllowSlow = false; // Don't allow slow
66 return GetTransaction(hash, txOut, hashBlock, fAllowSlow);
70 bool Eval::GetTxConfirmed(const uint256 &hash, CTransaction &txOut, CBlockIndex &block) const
73 if (!GetTxUnconfirmed(hash, txOut, hashBlock))
75 if (hashBlock.IsNull() || !GetBlock(hashBlock, block))
81 unsigned int Eval::GetCurrentHeight() const
83 return chainActive.Height();
87 bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
89 auto r = mapBlockIndex.find(hash);
90 if (r != mapBlockIndex.end()) {
91 blockIdx = *r->second;
94 fprintf(stderr, "CC Eval Error: Can't get block from index\n");
99 extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
102 int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
104 return komodo_notaries(pubkeys, height, timestamp);
108 bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
110 if (tx.vin.size() < 11) return false;
112 uint8_t seenNotaries[64] = {0};
113 uint8_t notaries[64][33];
114 int nNotaries = GetNotaries(notaries, height, timestamp);
116 BOOST_FOREACH(const CTxIn &txIn, tx.vin)
121 if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false;
122 if (tx.vout.size() < txIn.prevout.n) return false;
123 CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
124 if (spk.size() != 35) return false;
125 const unsigned char *pk = spk.data();
126 if (pk++[0] != 33) return false;
127 if (pk[33] != OP_CHECKSIG) return false;
129 // Check it's a notary
130 for (int i=0; i<nNotaries; i++) {
131 if (!seenNotaries[i]) {
132 if (memcmp(pk, notaries[i], 33) == 0) {
147 * Get MoM from a notarisation tx hash
149 bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
151 CTransaction notarisationTx;
153 if (!GetTxConfirmed(notaryHash, notarisationTx, block)) return false;
154 if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false;
155 if (notarisationTx.vout.size() < 2) return false;
156 if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false;
162 * Notarisation data, ie, OP_RETURN payload in notarisation transactions
164 extern char ASSETCHAINS_SYMBOL[16];
166 bool NotarisationData::Parse(const CScript scriptPK)
168 *this = NotarisationData();
170 std::vector<unsigned char> vdata;
171 if (!GetOpReturnData(scriptPK, vdata)) return false;
173 CDataStream ss(vdata, SER_NETWORK, PROTOCOL_VERSION);
178 if (ASSETCHAINS_SYMBOL[0])
181 char *nullPos = (char*) memchr(&ss[0], 0, ss.size());
182 if (!nullPos) return false;
183 ss.read(symbol, nullPos-&ss[0]+1);
185 if (ss.size() < 36) return false;
199 std::string EvalToStr(EvalCode c)
201 FOREACH_EVAL(EVAL_GENERATE_STRING);
203 sprintf(s, "0x%x", c);
204 return std::string(s);