Skip to content

Commit

Permalink
Merge pull request #36 from marmarachain/development
Browse files Browse the repository at this point in the history
merge request to master
  • Loading branch information
marmarachain committed Mar 28, 2023
2 parents a92d834 + 3b7d903 commit 470bbbb
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 27 deletions.
6 changes: 5 additions & 1 deletion src/cc/eval.cpp
Expand Up @@ -34,12 +34,16 @@ Eval* EVAL_TEST = 0;
struct CCcontract_info CCinfos[0x100];
extern pthread_mutex_t KOMODO_CC_mutex;

bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn)
bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn, CValidationState *pstateCC)
{
EvalRef eval;
pthread_mutex_lock(&KOMODO_CC_mutex);
bool out = eval->Dispatch(cond, tx, nIn);
pthread_mutex_unlock(&KOMODO_CC_mutex);

if (pstateCC) {
*pstateCC = eval->state; // return cc validation state
}
if ( eval->state.IsValid() != out)
fprintf(stderr,"out %d vs %d isValid\n",(int32_t)out,(int32_t)eval->state.IsValid());
//assert(eval->state.IsValid() == out);
Expand Down
14 changes: 10 additions & 4 deletions src/cc/eval.h
Expand Up @@ -77,8 +77,9 @@ class Eval
public:
CValidationState state;

bool Invalid(std::string s) { return state.Invalid(false, 0, s); }
bool Invalid(std::string s) { return state.Invalid(false, 100, s); } // set by default DoS to 100
bool Error(std::string s) { return state.Error(s); }
bool Invalid(std::string s, int nDoS) { return state.Invalid(false, nDoS, s); } // allow to set DoS
bool Valid() { return true; }

/*
Expand Down Expand Up @@ -132,9 +133,14 @@ class EvalRef : public EvalRef_
[](Eval* e){if (e!=EVAL_TEST) delete e;}) { }
};



bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn);
/**
* run cc validators for evalcodes in the cond
* @param cond cryptocondition from a tx cc input
* @param tx transaction
* @param nIn tx input index
* @param[out] pstateCC ptr to output CValidationState set by the evalcode validator (optional)
*/
bool RunCCEval(const CC *cond, const CTransaction &tx, unsigned int nIn, CValidationState *pstateCC = nullptr);


/*
Expand Down
11 changes: 10 additions & 1 deletion src/cc/marmara.cpp
Expand Up @@ -2421,6 +2421,7 @@ bool MarmaraValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction
CPubKey Marmarapk = GetUnspendable(cp, 0);
std::string validationError;
std::set<uint8_t> funcIds;
int nDoS = 100; // DoS level by default

for (int32_t i = 0; i < tx.vout.size(); i++)
{
Expand Down Expand Up @@ -2564,11 +2565,13 @@ bool MarmaraValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction
{
if (check_settlement_tx(tx, validationError))
return true;
nDoS = 0; // do not ban settlement tx
}
else if (funcIds == std::set<uint8_t>{MARMARA_SETTLE_PARTIAL}) // insufficient settlement
{
if (check_settlement_tx(tx, validationError))
return true;
nDoS = 0; // do not ban settlement tx
}
else if (funcIds == std::set<uint8_t>{MARMARA_COINBASE} || funcIds == std::set<uint8_t>{MARMARA_COINBASE_3X }) // coinbase
{
Expand Down Expand Up @@ -2602,7 +2605,7 @@ bool MarmaraValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction
validationError = "invalid funcid combination";

LOGSTREAMFN("marmara", CCLOG_ERROR, stream << " validation error '" << validationError << "' for tx=" << HexStr(E_MARSHAL(ss << tx)) << std::endl);
return eval->Error(validationError);
return eval->Invalid(validationError, nDoS);
}
// end of consensus code

Expand Down Expand Up @@ -3885,6 +3888,7 @@ UniValue MarmaraSettlement(int64_t txfee, uint256 refbatontxid, CTransaction &se

int64_t change = 0;
//int32_t height = chainActive.LastTip()->GetHeight();
LOCK(cs_main);
if ((numDebtors = MarmaraGetbatontxid(creditloop, batontxid, refbatontxid)) > 0)
{
CTransaction batontx;
Expand Down Expand Up @@ -4117,6 +4121,7 @@ static int32_t enum_credit_loops(int32_t nVoutMarker, struct CCcontract_info *cp
uint256 hashBlock;
uint8_t funcid;

LOCK(cs_main);
if (get_settlement_txid(settletxid, issuancetxid) == 0)
{
LOGSTREAMFN("marmara", CCLOG_DEBUG2, stream << "found settle tx for issueancetxid=" << issuancetxid.GetHex() << std::endl);
Expand Down Expand Up @@ -4194,6 +4199,8 @@ void MarmaraRunAutoSettlement(int32_t height, std::vector<CTransaction> & settle
{
LOGSTREAM("marmara", CCLOG_DEBUG2, stream << funcname << " " << "miner calling settlement for batontxid=" << batontxid.GetHex() << std::endl);

// do not call LOCK(cs_main), it is already called in enum_credit_loops
// also LOCK(cs_main) is called in MarmaraSettlement but should not create a problem
UniValue result = MarmaraSettlement(0, batontxid, newSettleTx);
if (result["result"].getValStr() == "success") {
LOGSTREAM("marmara", CCLOG_INFO, stream << funcname << " " << "miner created settlement tx=" << newSettleTx.GetHash().GetHex() << ", for batontxid=" << batontxid.GetHex() << std::endl);
Expand Down Expand Up @@ -4481,6 +4488,7 @@ UniValue MarmaraIssue(const CPubKey &remotepk, int64_t txfee, uint8_t funcid, co

uint256 dummytxid;
std::vector<uint256> creditloop;
LOCK(cs_main);
int32_t endorsersNumber = MarmaraGetbatontxid(creditloop, dummytxid, requesttxid);

int32_t height = get_next_height();
Expand Down Expand Up @@ -4682,6 +4690,7 @@ UniValue MarmaraCreditloop(const CPubKey & remotepk, uint256 txid)
mypk = pubkey2pk(Mypubkey());

cp = CCinit(&C, EVAL_MARMARA);
LOCK(cs_main);
if ((n = MarmaraGetbatontxid(creditloop, batontxid, txid)) > 0)
{
if (get_loop_creation_data(creditloop[0], loopData, MARMARA_OPRET_VERSION_ANY) == 0)
Expand Down
6 changes: 4 additions & 2 deletions src/main.cpp
Expand Up @@ -2795,7 +2795,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error, &stateCC)) {
return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
}
return true;
Expand Down Expand Up @@ -2970,7 +2970,9 @@ bool ContextualCheckInputs(
// as to the correct behavior - we may want to continue
// peering with non-upgraded nodes even after a soft-fork
// super-majority vote has passed.
return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
int nDoS = 100;
check.IsInvalidCC(nDoS); // allow cc override DoS level
return state.DoS(nDoS,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/main.h
Expand Up @@ -38,6 +38,7 @@
#include "script/serverchecker.h"
#include "script/standard.h"
#include "script/script_ext.h"
#include "consensus/validation.h"
#include "spentindex.h"
#include "sync.h"
#include "tinyformat.h"
Expand Down Expand Up @@ -771,6 +772,7 @@ class CScriptCheck
uint32_t consensusBranchId;
ScriptError error;
PrecomputedTransactionData *txdata;
CValidationState stateCC;

public:
CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), consensusBranchId(0), error(SCRIPT_ERR_UNKNOWN_ERROR) {}
Expand All @@ -790,9 +792,11 @@ class CScriptCheck
std::swap(consensusBranchId, check.consensusBranchId);
std::swap(error, check.error);
std::swap(txdata, check.txdata);
std::swap(stateCC, check.stateCC);
}

ScriptError GetScriptError() const { return error; }
bool IsInvalidCC(int &nDoSOut) const { return stateCC.IsInvalid(nDoSOut); }
};

bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes);
Expand Down
1 change: 1 addition & 0 deletions src/rpc/marmararpc.cpp
Expand Up @@ -309,6 +309,7 @@ UniValue marmara_transfer(const UniValue& params, bool fHelp, const CPubKey& rem
throw runtime_error("incorrect requesttxid\n");

// find the baton for transfer call:
LOCK(cs_main);
if (MarmaraGetbatontxid(creditloop, batontxid, requesttxid) < 0)
throw runtime_error("couldnt find batontxid\n");

Expand Down
29 changes: 19 additions & 10 deletions src/script/interpreter.cpp
Expand Up @@ -259,7 +259,8 @@ bool EvalScript(
unsigned int flags,
const BaseSignatureChecker& checker,
uint32_t consensusBranchId,
ScriptError* serror)
ScriptError* serror,
CValidationState *pstateCC)
{
static const CScriptNum bnZero(0);
static const CScriptNum bnOne(1);
Expand Down Expand Up @@ -972,7 +973,7 @@ bool EvalScript(
if (stack.size() < 2)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
//fprintf(stderr,"check cryptocondition\n");
int fResult = checker.CheckCryptoCondition(stacktop(-1), stacktop(-2), script, consensusBranchId);
int fResult = checker.CheckCryptoCondition(stacktop(-1), stacktop(-2), script, consensusBranchId, pstateCC);
if (fResult == -1) {
return set_error(serror, SCRIPT_ERR_CRYPTOCONDITION_INVALID_FULFILLMENT);
}
Expand Down Expand Up @@ -1358,12 +1359,17 @@ bool TransactionSignatureChecker::CheckSig(
return true;
}

typedef struct {
const TransactionSignatureChecker *checker;
CValidationState *pstateCC;
} EVAL_STATE_CONTEXT;

int TransactionSignatureChecker::CheckCryptoCondition(
const std::vector<unsigned char>& condBin,
const std::vector<unsigned char>& ffillBin,
const CScript& scriptCode,
uint32_t consensusBranchId) const
uint32_t consensusBranchId,
CValidationState *pstateCC) const
{
// Hash type is one byte tacked on to the end of the fulfillment
if (ffillBin.empty())
Expand Down Expand Up @@ -1392,20 +1398,22 @@ int TransactionSignatureChecker::CheckCryptoCondition(
fprintf(stderr,"%02x",((uint8_t *)&sighash)[z]);
fprintf(stderr," sighash nIn.%d nHashType.%d %.8f id.%d\n",(int32_t)nIn,(int32_t)nHashType,(double)amount/COIN,(int32_t)consensusBranchId);
*/
VerifyEval eval = [] (CC *cond, void *checker) {
VerifyEval eval = [] (CC *cond, void *pctx) {
EVAL_STATE_CONTEXT *pstate_ctx = (EVAL_STATE_CONTEXT *)pctx;
//fprintf(stderr,"checker.%p\n",(TransactionSignatureChecker*)checker);
return ((TransactionSignatureChecker*)checker)->CheckEvalCondition(cond);
return pstate_ctx->checker->CheckEvalCondition(cond, pstate_ctx->pstateCC);
};
//fprintf(stderr,"non-checker path\n");
EVAL_STATE_CONTEXT ctx { this, pstateCC };
int out = cc_verify(cond, (const unsigned char*)&sighash, 32, 0,
condBin.data(), condBin.size(), eval, (void*)this);
condBin.data(), condBin.size(), eval, (void*)&ctx);
//fprintf(stderr,"out.%d from cc_verify\n",(int32_t)out);
cc_free(cond);
return out;
}


int TransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
int TransactionSignatureChecker::CheckEvalCondition(const CC *cond, CValidationState *pstateCC) const
{
//fprintf(stderr, "Cannot check crypto-condition Eval outside of server, returning true in pre-checks\n");
return true;
Expand Down Expand Up @@ -1492,7 +1500,8 @@ bool VerifyScript(
unsigned int flags,
const BaseSignatureChecker& checker,
uint32_t consensusBranchId,
ScriptError* serror)
ScriptError* serror,
CValidationState *pstateCC)
{
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);

Expand All @@ -1506,12 +1515,12 @@ bool VerifyScript(
// serror is set
return false;
}
else if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror))
else if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror, pstateCC))
// serror is set
return false;
if (flags & SCRIPT_VERIFY_P2SH)
stackCopy = stack;
if (!EvalScript(stack, scriptPubKey, flags, checker, consensusBranchId, serror))
if (!EvalScript(stack, scriptPubKey, flags, checker, consensusBranchId, serror, pstateCC))
// serror is set
return false;
if (stack.empty())
Expand Down
18 changes: 12 additions & 6 deletions src/script/interpreter.h
Expand Up @@ -24,6 +24,8 @@
#include "script_error.h"
#include "primitives/transaction.h"
#include "script/cc.h"
#include "../consensus/validation.h"


#include <vector>
#include <stdint.h>
Expand Down Expand Up @@ -150,7 +152,8 @@ class BaseSignatureChecker
const std::vector<unsigned char>& condBin,
const std::vector<unsigned char>& ffillBin,
const CScript& scriptCode,
uint32_t consensusBranchId) const
uint32_t consensusBranchId,
CValidationState *pstateCC = NULL) const
{
return false;
}
Expand All @@ -173,12 +176,13 @@ class TransactionSignatureChecker : public BaseSignatureChecker
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
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;
int CheckCryptoCondition(
virtual int CheckCryptoCondition(
const std::vector<unsigned char>& condBin,
const std::vector<unsigned char>& ffillBin,
const CScript& scriptCode,
uint32_t consensusBranchId) const;
virtual int CheckEvalCondition(const CC *cond) const;
uint32_t consensusBranchId,
CValidationState *pstateCC = NULL) const;
virtual int CheckEvalCondition(const CC *cond, CValidationState *pstateCC = NULL) const;
};

class MutableTransactionSignatureChecker : public TransactionSignatureChecker
Expand All @@ -196,12 +200,14 @@ bool EvalScript(
unsigned int flags,
const BaseSignatureChecker& checker,
uint32_t consensusBranchId,
ScriptError* error = NULL);
ScriptError* error = NULL,
CValidationState *pstateCC = NULL);
bool VerifyScript(
const CScript& scriptSig,
const CScript& scriptPubKey,
unsigned int flags,
const BaseSignatureChecker& checker,
uint32_t consensusBranchId,
ScriptError* serror = NULL);
ScriptError* serror = NULL,
CValidationState *pstateCC = NULL);
#endif // BITCOIN_SCRIPT_INTERPRETER_H
4 changes: 2 additions & 2 deletions src/script/serverchecker.cpp
Expand Up @@ -116,8 +116,8 @@ bool ServerTransactionSignatureChecker::VerifySignature(const std::vector<unsign
* code without pulling the whole bitcoin server code into bitcoin common was
* using this class. Thus it has been renamed to ServerTransactionSignatureChecker.
*/
int ServerTransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
int ServerTransactionSignatureChecker::CheckEvalCondition(const CC *cond, CValidationState *pstateCC) const
{
//fprintf(stderr,"call RunCCeval from ServerTransactionSignatureChecker::CheckEvalCondition\n");
return RunCCEval(cond, *txTo, nIn);
return RunCCEval(cond, *txTo, nIn, pstateCC);
}
2 changes: 1 addition & 1 deletion src/script/serverchecker.h
Expand Up @@ -37,7 +37,7 @@ class ServerTransactionSignatureChecker : public TransactionSignatureChecker
ServerTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, nIn, amount), store(storeIn) {}

bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
int CheckEvalCondition(const CC *cond) const;
virtual int CheckEvalCondition(const CC *cond, CValidationState *pstateCC = NULL) const;
};

#endif // BITCOIN_SCRIPT_SERVERCHECKER_H

0 comments on commit 470bbbb

Please sign in to comment.