ImportPayout cc eval code and alot of general cc polish. tests to write

This commit is contained in:
Scott Sadler
2018-03-30 15:46:41 -03:00
parent 991c422a9d
commit 2c8d8268dd
25 changed files with 389 additions and 116 deletions

View File

@@ -43,7 +43,7 @@ LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
LIBSECP256K1=secp256k1/libsecp256k1.la
LIBCRYPTOCONDITIONS=cryptoconditions/cryptoconditions_core.a
LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la
LIBSNARK=snark/libsnark.a
LIBUNIVALUE=univalue/libunivalue.la
LIBZCASH=libzcash.a -lcurl
@@ -135,6 +135,7 @@ BITCOIN_CORE_H = \
asyncrpcqueue.h \
base58.h \
bloom.h \
cc/eval.h \
chain.h \
chainparams.h \
chainparamsbase.h \
@@ -162,7 +163,7 @@ BITCOIN_CORE_H = \
init.h \
key.h \
keystore.h \
komodo_cryptoconditions.h \
komodo_cc.h \
leveldbwrapper.h \
limitedmap.h \
main.h \
@@ -191,7 +192,7 @@ BITCOIN_CORE_H = \
script/interpreter.h \
script/script.h \
script/script_error.h \
script/sigcache.h \
script/serverchecker.h \
script/sign.h \
script/standard.h \
serialize.h \
@@ -249,13 +250,14 @@ libbitcoin_server_a_SOURCES = \
asyncrpcoperation.cpp \
asyncrpcqueue.cpp \
bloom.cpp \
cc/eval.cpp \
cc/importpayout.cpp \
chain.cpp \
checkpoints.cpp \
deprecation.cpp \
httprpc.cpp \
httpserver.cpp \
init.cpp \
komodo_cryptoconditions.cpp \
leveldbwrapper.cpp \
main.cpp \
merkleblock.cpp \
@@ -274,7 +276,7 @@ libbitcoin_server_a_SOURCES = \
rpcnet.cpp \
rpcrawtransaction.cpp \
rpcserver.cpp \
script/sigcache.cpp \
script/serverchecker.cpp \
timedata.cpp \
torcontrol.cpp \
txdb.cpp \
@@ -378,7 +380,6 @@ libbitcoin_common_a_SOURCES = \
hash.cpp \
key.cpp \
keystore.cpp \
komodo_cryptoconditions.cpp \
netbase.cpp \
primitives/block.cpp \
primitives/transaction.cpp \

View File

@@ -25,4 +25,6 @@ zcash_CreateJoinSplit_LDADD = \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(BOOST_LIBS) \
$(LIBZCASH_LIBS)
$(LIBZCASH_LIBS) \
$(LIBCRYPTOCONDITIONS) \
$(LIBSECP256K1)

23
src/cc/eval.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "primitives/transaction.h"
#include "komodo_cc.h"
#include "cc/eval.h"
#include <cryptoconditions.h>
/*
* Test the validity of an Eval node
*/
bool EvalConditionValidity(const CC *cond, const CTransaction *txTo, int nIn)
{
if (strcmp(cond->method, "testEval") == 0) {
return cond->paramsBinLength == 8 &&
memcmp(cond->paramsBin, "testEval", 8) == 0;
}
if (strcmp(cond->method, "ImportPayout") == 0) {
return CheckImportPayout(cond, txTo, nIn);
}
fprintf(stderr, "no defined behaviour for method: %s\n", cond->method);
return 0;
}

18
src/cc/eval.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef CC_EVAL_H
#define CC_EVAL_H
#include "cryptoconditions/include/cryptoconditions.h"
#include "primitives/transaction.h"
/*
* Test validity of a CC_Eval node
*/
bool EvalConditionValidity(const CC *cond, const CTransaction *tx, int nIn);
/*
* Test an ImportPayout CC Eval condition
*/
bool CheckImportPayout(const CC *cond, const CTransaction *payoutTx, int nIn);
#endif /* CC_EVAL_H */

191
src/cc/importpayout.cpp Normal file
View File

@@ -0,0 +1,191 @@
#include "primitives/transaction.h"
#include "streams.h"
#include "chain.h"
#include "main.h"
#include "cryptoconditions/include/cryptoconditions.h"
bool GetPushData(const CScript &sig, std::vector<unsigned char> &data)
{
opcodetype opcode;
auto pc = sig.begin();
if (sig.GetOp(pc, opcode, data)) return opcode > OP_0 && opcode <= OP_PUSHDATA4;
return false;
}
bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data)
{
auto pc = sig.begin();
opcodetype opcode;
if (sig.GetOp2(pc, opcode, NULL))
if (opcode == OP_RETURN)
if (sig.GetOp(pc, opcode, data))
return opcode > OP_0 && opcode <= OP_PUSHDATA4;
return false;
}
class MomProof
{
public:
uint256 notaryHash;
int nPos; // Position of imported tx in MoM
std::vector<uint256> branch;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(notaryHash);
READWRITE(VARINT(nPos));
READWRITE(branch);
}
};
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
bool DerefNotaryPubkey(const COutPoint &prevout, char *pk33)
{
CTransaction tx;
uint256 hashBlock;
if (!GetTransaction(prevout.hash, tx, hashBlock, false)) return false;
if (tx.vout.size() < prevout.n) return false;
const unsigned char *script = tx.vout[prevout.n].scriptPubKey.data();
if (script[0] != 33) return false;
memcpy(pk33, script+1, 33);
return true;
}
bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp)
{
if (tx.vin.size() < 11) return false;
uint8_t notaries[64][33];
uint8_t seenNotaries[64];
int nNotaries = komodo_notaries(notaries, height, timestamp);
char *pk;
BOOST_FOREACH(const CTxIn &txIn, tx.vin)
{
if (!DerefNotaryPubkey(txIn.prevout, pk)) return false;
for (int i=0; i<nNotaries; i++) {
if (!seenNotaries[i]) {
if (memcmp(pk, notaries[i], 33) == 0) {
seenNotaries[i] = 1;
goto found;
}
}
}
return false;
found:;
}
}
/*
* Get MoM from a notarisation tx hash
*/
bool GetMoM(const uint256 notaryHash, uint256 &mom)
{
CTransaction notarisationTx;
uint256 notarisationBlock;
if (!GetTransaction(notaryHash, notarisationTx, notarisationBlock, true)) return 0;
CBlockIndex* blockindex = mapBlockIndex[notarisationBlock];
if (!CheckNotaryInputs(notarisationTx, blockindex->nHeight, blockindex->nTime)) {
return false;
}
if (!notarisationTx.vout.size() < 1) return 0;
std::vector<unsigned char> opret;
if (!GetOpReturnData(notarisationTx.vout[0].scriptPubKey, opret)) return 0;
if (opret.size() < 36) return 0; // In reality it is more than 36, but at the moment I
// only know where it is relative to the end, and this
// is enough to prevent a memory fault. In the case that
// the assumption about the presence of a MoM at this
// offset fails, we will return random other data that is
// not more likely to generate a false positive.
memcpy(mom.begin(), opret.data()+opret.size()-36, 32);
return 1;
}
uint256 ExecMerkle(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
return CBlock::CheckMerkleBranch(hash, vMerkleBranch, nIndex);
}
/*
* Crypto-Condition EVAL method that verifies a payout against a transaction
* notarised on another chain.
*
* IN: cond - CC EVAL node
* IN: payoutTx - Payout transaction on value chain (KMD)
* IN: nIn - index of input of stake
*
* payoutTx: Spends stakeTx with payouts from asset chain
*
* in 0: Spends Stake TX and contains ImportPayout CC
* out 0: OP_RETURN MomProof
* out 1: OP_RETURN serialized exportTx from other chain
* out 2-: arbitrary payouts
*
* exportTx: Spends sessionTx.0 (opener on asset chain)
*
* in 0: spends sessionTx.0
* in 1-: anything
* out 0: OP_RETURN hash of payouts
* out 1-: anything
*/
bool CheckImportPayout(const CC *cond, const CTransaction *payoutTx, int nIn)
{
// TODO: Error messages!
if (payoutTx->vin.size() != 1) return 0;
if (payoutTx->vout.size() < 2) return 0;
// Get hash of payouts
std::vector<CTxOut> payouts(payoutTx->vout.begin() + 2, payoutTx->vout.end());
uint256 payoutsHash = SerializeHash(payouts);
std::vector<unsigned char> vPayoutsHash(payoutsHash.begin(), payoutsHash.end());
// load exportTx from vout[1]
CTransaction exportTx;
{
std::vector<unsigned char> exportData;
if (!GetOpReturnData(payoutTx->vout[1].scriptPubKey, exportData)) return 0;
CDataStream(exportData, SER_DISK, PROTOCOL_VERSION) >> exportTx;
// TODO: end of stream? exception?
}
// Check exportTx.0 is vPayoutsHash
std::vector<unsigned char> exportPayoutsHash;
if (!GetOpReturnData(exportTx.vout[0].scriptPubKey, exportPayoutsHash)) return 0;
if (exportPayoutsHash != vPayoutsHash) return 0;
// Check exportTx spends sessionTx.0
// condition ImportPayout params is session ID from other chain
{
if (cond->paramsBinLength != 32) return 0;
COutPoint prevout = exportTx.vin[0].prevout;
if (memcmp(prevout.hash.begin(), cond->paramsBin, 32) != 0 ||
prevout.n != 0) return 0;
}
// Check exportTx solves momproof from vout[0]
{
std::vector<unsigned char> vchMomProof;
if (!GetOpReturnData(payoutTx->vout[0].scriptPubKey, vchMomProof)) return 0;
MomProof momProof;
CDataStream(vchMomProof, SER_DISK, PROTOCOL_VERSION) >> momProof;
uint256 mom;
if (!GetMoM(momProof.notaryHash, mom)) return 0;
uint256 proofResult = ExecMerkle(exportTx.GetHash(), momProof.branch, momProof.nPos);
if (proofResult != mom) return 0;
}
return 1;
}

View File

@@ -2,6 +2,8 @@ lib_LTLIBRARIES=libcryptoconditions.la
noinst_LTLIBRARIES=$(CRYPTOCONDITIONS_CORE)
SUBDIRS = src/include/secp256k1
include_HEADERS = include/cryptoconditions.h
# Have a separate build target for cryptoconditions that does not contain secp256k1
libcryptoconditions_la_SOURCES = include/cryptoconditions.h

View File

@@ -84,9 +84,9 @@ unsigned char* cc_conditionUri(const CC *cond);
unsigned char* cc_jsonRPC(unsigned char *request);
unsigned long cc_getCost(const CC *cond);
enum CCTypeId cc_typeId(const CC *cond);
uint32_t cc_typeMask(const CC *cond);
void cc_free(struct CC *cond);
#ifdef __cplusplus
}
#endif

View File

@@ -42,8 +42,8 @@ void appendUriSubtypes(uint32_t mask, unsigned char *buf) {
} else {
strcat(buf, "&subtypes=");
strcat(buf, typeRegistry[i]->name);
append = 1;
}
append = 1;
}
}
}
@@ -70,7 +70,7 @@ unsigned char *cc_conditionUri(const CC *cond) {
}
static uint32_t getSubtypes(CC *cond) {
uint32_t cc_typeMask(const CC *cond) {
uint32_t mask = 1 << cond->type->typeId;
if (cond->type->hasSubtypes) {
mask |= cond->type->getSubtypes(cond);

View File

@@ -49,7 +49,6 @@ static CC *mkAnon(const Condition_t *asnCond);
static void asnCondition(const CC *cond, Condition_t *asn);
static Condition_t *asnConditionNew(const CC *cond);
static Fulfillment_t *asnFulfillmentNew(const CC *cond);
static uint32_t getSubtypes(CC *cond);
static cJSON *jsonEncodeCondition(cJSON *params, unsigned char *err);
static struct CC *fulfillmentToCC(Fulfillment_t *ffill);
static struct CCType *getTypeByAsnEnum(Condition_PR present);

View File

@@ -71,7 +71,7 @@ static Fulfillment_t *prefixToFulfillment(const CC *cond) {
static uint32_t prefixSubtypes(const CC *cond) {
return getSubtypes(cond->subcondition) & ~(1 << cc_prefixType.typeId);
return cc_typeMask(cond->subcondition) & ~(1 << cc_prefixType.typeId);
}

View File

@@ -98,7 +98,7 @@ int secp256k1Verify(CC *cond, CCVisitor visitor) {
static int cc_secp256k1VerifyTreeMsg32(const CC *cond, const unsigned char *msg32) {
int subtypes = getSubtypes(cond);
int subtypes = cc_typeMask(cond);
if (subtypes & (1 << cc_prefixType.typeId) &&
subtypes & (1 << cc_secp256k1Type.typeId)) {
// No support for prefix currently, due to pending protocol decision on
@@ -148,7 +148,7 @@ static int secp256k1Sign(CC *cond, CCVisitor visitor) {
* Sign secp256k1 conditions in a tree
*/
int cc_signTreeSecp256k1Msg32(CC *cond, const unsigned char *privateKey, const unsigned char *msg32) {
if (getSubtypes(cond) & (1 << cc_preimageType.typeId)) {
if (cc_typeMask(cond) & (1 << cc_preimageType.typeId)) {
// No support for prefix currently, due to pending protocol decision on
// how to combine message and prefix into 32 byte hash
return 0;

View File

@@ -14,7 +14,7 @@ struct CCType cc_thresholdType;
static uint32_t thresholdSubtypes(const CC *cond) {
uint32_t mask = 0;
for (int i=0; i<cond->size; i++) {
mask |= getSubtypes(cond->subconditions[i]);
mask |= cc_typeMask(cond->subconditions[i]);
}
mask &= ~(1 << cc_thresholdType.typeId);
return mask;

40
src/komodo_cc.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef KOMODO_CC_H
#define KOMODO_CC_H
#include "cryptoconditions/include/cryptoconditions.h"
#include "primitives/transaction.h"
/*
* Check if CryptoConditions is enabled based on chain or cmd flag
*/
extern int32_t ASSETCHAINS_CC;
static bool IsCryptoConditionsEnabled()
{
return 0 != ASSETCHAINS_CC;
}
/*
* Check if the server can accept the condition based on it's structure / types
*/
static bool IsAcceptableCryptoCondition(const CC *cond)
{
int32_t typeMask = cc_typeMask(cond);
// Require a signature to prevent transaction malleability
if (0 == typeMask & (1 << CC_Secp256k1) ||
0 == typeMask & (1 << CC_Ed25519)) return false;
// Limit acceptable condition types
// Prefix not enabled because no current use case, ambiguity on how to combine with secp256k1
// RSA not enabled because no current use case, not implemented
int enabledTypes = 1 << CC_Secp256k1 | 1 << CC_Threshold | 1 << CC_Eval | \
1 << CC_Preimage | 1 << CC_Ed25519;
if (typeMask & ~enabledTypes) return false;
return true;
}
#endif /* KOMODO_CC_H */

View File

@@ -1,28 +0,0 @@
#include "komodo_cryptoconditions.h"
#include "cryptoconditions/include/cryptoconditions.h"
/*
* Evaluate the validity of an Eval node
*/
bool EvalConditionValidity(const CC *cond, const CTransaction *txTo)
{
if (strcmp(cond->method, "testEval") == 0) {
return cond->paramsBinLength == 8 &&
memcmp(cond->paramsBin, "testEval", 8) == 0;
}
fprintf(stderr, "no defined behaviour for method: %s\n", cond->method);
return 0;
}
bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data)
{
auto pc = sig.begin();
opcodetype opcode;
if (sig.GetOp(pc, opcode))
if (opcode == OP_RETURN)
if (sig.GetOp(pc, opcode, data))
return opcode > OP_0 && opcode <= OP_PUSHDATA4;
return false;
}

View File

@@ -1,19 +0,0 @@
#ifndef KOMODO_CRYPTOCONDITIONS_H
#define KOMODO_CRYPTOCONDITIONS_H
#include "cryptoconditions/include/cryptoconditions.h"
#include "primitives/transaction.h"
#include "script/script.h"
extern int32_t ASSETCHAINS_CC;
static bool IsCryptoConditionsEnabled() {
return 0 != ASSETCHAINS_CC;
}
bool EvalConditionValidity(const CC *cond, const CTransaction *tx);
bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data);
#endif /* KOMODO_CRYPTOCONDITIONS_H */

View File

@@ -1931,7 +1931,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), consensusBranchId, &error)) {
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, ServerTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), consensusBranchId, &error)) {
return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
}
return true;

View File

@@ -20,7 +20,7 @@
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "script/script.h"
#include "script/sigcache.h"
#include "script/serverchecker.h"
#include "script/standard.h"
#include "sync.h"
#include "tinyformat.h"

View File

@@ -13,7 +13,7 @@
#include "pubkey.h"
#include "script/script.h"
#include "uint256.h"
#include "komodo_cryptoconditions.h"
#include "cryptoconditions/include/cryptoconditions.h"
using namespace std;
@@ -1295,20 +1295,10 @@ bool TransactionSignatureChecker::CheckSig(
}
bool TransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
{
return EvalConditionValidity(cond, txTo);
}
static int komodoCCEval(CC *cond, void *checker)
{
return ((TransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
}
bool TransactionSignatureChecker::CheckCryptoCondition(const CC *cond, const std::vector<unsigned char>& condBin, const CScript& scriptCode, uint32_t consensusBranchId) const
{
if (!IsAcceptableCryptoCondition(cond)) return false;
uint256 sighash;
try {
sighash = SignatureHash(scriptCode, *txTo, nIn, SIGHASH_ALL, amount, consensusBranchId, this->txdata);
@@ -1316,7 +1306,15 @@ bool TransactionSignatureChecker::CheckCryptoCondition(const CC *cond, const std
return false;
}
return cc_verify(cond, (const unsigned char*)&sighash, 32, 0,
condBin.data(), condBin.size(), komodoCCEval, (void*)this);
condBin.data(), condBin.size(), GetCCEval(), (void*)this);
}
VerifyEval TransactionSignatureChecker::GetCCEval() const {
return [] (CC *cond, void *checker) {
fprintf(stderr, "Cannot check crypto-condition Eval outside of server\n");
return 0;
};
}

View File

@@ -8,7 +8,7 @@
#include "script_error.h"
#include "primitives/transaction.h"
#include "komodo_cryptoconditions.h"
#include "komodo_cc.h"
#include <vector>
#include <stdint.h>
@@ -153,7 +153,7 @@ public:
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const;
bool CheckLockTime(const CScriptNum& nLockTime) const;
bool CheckCryptoCondition(const CC *cond, const std::vector<unsigned char>& condBin, const CScript& scriptCode, uint32_t consensusBranchId) const;
bool CheckEvalCondition(const CC *cond) const;
VerifyEval GetCCEval() const;
};
class MutableTransactionSignatureChecker : public TransactionSignatureChecker

View File

@@ -7,6 +7,8 @@
#include "tinyformat.h"
#include "utilstrencodings.h"
#include "komodo_cc.h"
#include "cryptoconditions/include/cryptoconditions.h"
namespace {
inline std::string ValueString(const std::vector<unsigned char>& vch)
@@ -238,6 +240,20 @@ bool CScript::IsPayToCryptoCondition() const
return 0;
}
bool CScript::MayAcceptCryptoCondition() const
{
// Get the type mask of the condition
const_iterator pc = this->begin();
vector<unsigned char> data;
opcodetype opcode;
if (!this->GetOp(pc, opcode, data)) return false;
if (!(opcode > OP_0 && opcode < OP_PUSHDATA1)) return false;
CC *cond = cc_readConditionBinary(data.data(), data.size());
if (!cond) return false;
bool accept = IsAcceptableCryptoCondition(cond);
return accept;
}
bool CScript::IsPushOnly() const
{
const_iterator pc = begin();

View File

@@ -565,6 +565,7 @@ public:
bool IsPayToScriptHash() const;
bool IsPayToCryptoCondition() const;
bool MayAcceptCryptoCondition() const;
/** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
bool IsPushOnly() const;

View File

@@ -3,7 +3,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sigcache.h"
#include "serverchecker.h"
#include "komodo_cc.h"
#include "cc/eval.h"
#include "pubkey.h"
#include "random.h"
@@ -26,13 +28,13 @@ private:
//! sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
std::set< sigdata_type> setValid;
boost::shared_mutex cs_sigcache;
boost::shared_mutex cs_serverchecker;
public:
bool
Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
{
boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
boost::shared_lock<boost::shared_mutex> lock(cs_serverchecker);
sigdata_type k(hash, vchSig, pubKey);
std::set<sigdata_type>::iterator mi = setValid.find(k);
@@ -47,10 +49,10 @@ public:
// (~200 bytes per cache entry times 50,000 entries)
// Since there can be no more than 20,000 signature operations per block
// 50,000 is a reasonable default.
int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
int64_t nMaxCacheSize = GetArg("-maxservercheckersize", 50000);
if (nMaxCacheSize <= 0) return;
boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
boost::unique_lock<boost::shared_mutex> lock(cs_serverchecker);
while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize)
{
@@ -74,7 +76,7 @@ public:
}
bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
bool ServerTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
static CSignatureCache signatureCache;
@@ -88,3 +90,24 @@ bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsig
signatureCache.Set(sighash, vchSig, pubkey);
return true;
}
/*
* The reason that these functions are here is that the what used to be the
* CachingTransactionSignatureChecker, now the ServerTransactionSignatureChecker,
* is an entry point that the server uses to validate signatures and which is not
* included as part of bitcoin common libs. Since Crypto-Condtions eval methods
* may call server code (GetTransaction etc), the best way to get it to run this
* code without pulling the whole bitcoin server code into bitcoin common was
* using this class. Thus it has been renamed to ServerTransactionSignatureChecker.
*/
VerifyEval ServerTransactionSignatureChecker::GetCCEval() const
{
return [] (CC *cond, void *checker) {
return ((ServerTransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
};
}
int ServerTransactionSignatureChecker::CheckEvalCondition(CC *cond) const
{
return EvalConditionValidity(cond, txTo, nIn);
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SERVERCHECKER_H
#define BITCOIN_SCRIPT_SERVERCHECKER_H
#include "script/interpreter.h"
#include <vector>
class CPubKey;
class ServerTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
bool store;
const CTransaction* txTo;
unsigned int nIn;
public:
ServerTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
int CheckEvalCondition(CC *cond) const;
VerifyEval GetCCEval() const;
};
#endif // BITCOIN_SCRIPT_SERVERCHECKER_H

View File

@@ -1,26 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SIGCACHE_H
#define BITCOIN_SCRIPT_SIGCACHE_H
#include "script/interpreter.h"
#include <vector>
class CPubKey;
class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
bool store;
public:
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
};
#endif // BITCOIN_SCRIPT_SIGCACHE_H

View File

@@ -9,7 +9,7 @@
#include "script/script.h"
#include "util.h"
#include "utilstrencodings.h"
#include "komodo_cryptoconditions.h"
#include "komodo_cc.h"
#include <boost/foreach.hpp>
@@ -72,9 +72,11 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
if (IsCryptoConditionsEnabled()) {
// Shortcut for pay-to-crypto-condition
if (scriptPubKey.IsPayToCryptoCondition()) {
typeRet = TX_CRYPTOCONDITION;
// TODO: Extract solutions
return true;
if (scriptPubKey.MayAcceptCryptoCondition()) {
typeRet = TX_CRYPTOCONDITION;
return true;
}
return false;
}
}