From 7791d5023010419ebc8c69ae718f104a90a23b0b Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 10 Feb 2024 23:06:56 -0500 Subject: [PATCH] Delete more CCs #381 --- src/script/cc.cpp | 59 --- src/script/interpreter.cpp | 40 +- src/script/sign.cpp | 168 +------ src/test-hush/test_cryptoconditions.cpp | 203 -------- src/test-hush/test_eval_bet.cpp | 597 ------------------------ 5 files changed, 7 insertions(+), 1060 deletions(-) delete mode 100644 src/test-hush/test_cryptoconditions.cpp delete mode 100644 src/test-hush/test_eval_bet.cpp diff --git a/src/script/cc.cpp b/src/script/cc.cpp index d145398e3..395dcdafd 100644 --- a/src/script/cc.cpp +++ b/src/script/cc.cpp @@ -44,70 +44,11 @@ static unsigned char* CopyPubKey(CPubKey pkIn) } -CC* CCNewThreshold(int t, std::vector v) -{ - CC *cond = cc_new(CC_Threshold); - cond->threshold = t; - cond->size = v.size(); - cond->subconditions = (CC**) calloc(v.size(), sizeof(CC*)); - memcpy(cond->subconditions, v.data(), v.size() * sizeof(CC*)); - return cond; -} - - -CC* CCNewSecp256k1(CPubKey k) -{ - CC *cond = cc_new(CC_Secp256k1); - cond->publicKey = CopyPubKey(k); - return cond; -} - - -CC* CCNewEval(std::vector code) -{ - CC *cond = cc_new(CC_Eval); - cond->code = (unsigned char*) malloc(code.size()); - memcpy(cond->code, code.data(), code.size()); - cond->codeLength = code.size(); - return cond; -} - - CScript CCPubKey(const CC *cond) { return CScript(); } - -CScript CCSig(const CC *cond) -{ - return CScript(); -} - -std::vector CCSigVec(const CC *cond) -{ - unsigned char buf[10000]; - size_t len = cc_fulfillmentBinary(cond, buf, 10000); - auto ffill = std::vector(buf, buf+len); - ffill.push_back(1); // SIGHASH_ALL - return ffill; -} - -std::string CCShowStructure(CC *cond) -{ - std::string out; - return out; -} - - -CC* CCPrune(CC *cond) -{ - std::vector ffillBin; - GetPushData(CCSig(cond), ffillBin); - return cc_readFulfillmentBinary(ffillBin.data(), ffillBin.size()-1); -} - - bool GetPushData(const CScript &sig, std::vector &data) { opcodetype opcode; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index e11b6a39f..d3114470d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -958,6 +958,7 @@ bool EvalScript( } break; + /* case OP_CHECKCRYPTOCONDITION: case OP_CHECKCRYPTOCONDITIONVERIFY: { @@ -987,6 +988,7 @@ bool EvalScript( } } break; + */ INTERPRETER_DEFAULT: default: @@ -1361,43 +1363,7 @@ int TransactionSignatureChecker::CheckCryptoCondition( const CScript& scriptCode, uint32_t consensusBranchId) const { - // Hash type is one byte tacked on to the end of the fulfillment - if (ffillBin.empty()) - return false; - - CC *cond; - int error = cc_readFulfillmentBinaryExt((unsigned char*)ffillBin.data(), ffillBin.size()-1, &cond); - if (error || !cond) return -1; - - if (!IsSupportedCryptoCondition(cond)) return 0; - if (!IsSignedCryptoCondition(cond)) return 0; - - uint256 sighash; - int nHashType = ffillBin.back(); - try { - sighash = SignatureHash(CCPubKey(cond), *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata); - } catch (logic_error ex) { - return 0; - } - /*int32_t z; uint8_t *ptr; - ptr = (uint8_t *)scriptCode.data(); - for (z=0; zCheckEvalCondition(cond); - }; - //fprintf(stderr,"non-checker path\n"); - int out = cc_verify(cond, (const unsigned char*)&sighash, 32, 0, - condBin.data(), condBin.size(), eval, (void*)this); - //fprintf(stderr,"out.%d from cc_verify\n",(int32_t)out); - cc_free(cond); - return out; + return 0; } diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 4de9523c0..70e976514 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -72,19 +72,8 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, } //fprintf(stderr,"privkey (%s) for %s\n",NSPV_wifstr,EncodeDestination(key.GetPubKey().GetID()).c_str()); - if (scriptCode.IsPayToCryptoCondition()) + if (0) // scriptCode.IsPayToCryptoCondition()) { - CC *cc = (CC *)extraData; - // assume either 1of1 or 1of2. if the condition created by the - if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0) - { - fprintf(stderr,"CC tree error\n"); - return false; - } - vchSig = CCSigVec(cc); - if ( HUSH_NSPV_SUPERLITE ) - memset((uint8_t *)key.begin(),0,32); - return true; } else { @@ -139,25 +128,6 @@ static bool SignN(const vector& multisigdata, const BaseSignatureCreato return nSigned==nRequired; } -CC *CCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2) -{ - std::vector pks; - pks.push_back(CCNewSecp256k1(pk1)); - pks.push_back(CCNewSecp256k1(pk2)); - CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode)); - CC *Sig = CCNewThreshold(1, pks); - return CCNewThreshold(2, {condCC, Sig}); -} - -CC *CCcond1(uint8_t evalcode,CPubKey pk) -{ - std::vector pks; - pks.push_back(CCNewSecp256k1(pk)); - CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode)); - CC *Sig = CCNewThreshold(1, pks); - return CCNewThreshold(2, {condCC, Sig}); -} - std::vector &GetCryptoConditions() { static bool initialized = false; @@ -173,36 +143,12 @@ std::vector &GetCryptoConditions() bool GetCCByUnspendableAddress(struct CCcontract_info *cp, char *addrstr) { - std::vector &vCC = GetCryptoConditions(); - bool found = false; - - for (int i = 0; i < vCC.size(); i++) - { - if (strcmp(addrstr, vCC[i].unspendableCCaddr) == 0) - { - found = true; - *cp = vCC[i]; - break; - } - } - return found; + return false; } bool CCinitLite(struct CCcontract_info *cp, uint8_t evalcode) { - std::vector &vCC = GetCryptoConditions(); - bool found = false; - - for (int i = 0; i < vCC.size(); i++) - { - if (vCC[i].evalcode == evalcode) - { - found = true; - *cp = vCC[i]; - break; - } - } - return found; + return false; } bool _Getscriptaddress(char *destaddr, const CScript &scriptPubKey) @@ -222,118 +168,12 @@ bool _Getscriptaddress(char *destaddr, const CScript &scriptPubKey) CScript _CCPubKey(const CC *cond) { - unsigned char buf[1000]; - size_t len = cc_conditionBinary(cond, buf); - return CScript() << std::vector(buf, buf+len) << OP_CHECKCRYPTOCONDITION; + return CScript(); } static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scriptPubKey, vector &vSolutions, vector& ret, uint32_t consensusBranchId) { - CScript subScript; - vector vPK; - vector vParams = vector(); - COptCCParams p; - - // get information to sign with - CCcontract_info C; - - scriptPubKey.IsPayToCryptoCondition(&subScript, vParams); - if (vParams.empty()) - { - // get the keyID address of the cc and if it is an unspendable cc address, use its pubkey - // we have nothing else - char addr[64]; - if (_Getscriptaddress(addr, subScript) && GetCCByUnspendableAddress(&C, addr)) - { - vPK.push_back(CPubKey(ParseHex(C.CChexstr))); - p = COptCCParams(p.VERSION, C.evalcode, 1, 1, vPK, vParams); - } - } - else - { - p = COptCCParams(vParams[0]); - } - - if (p.IsValid() && p.vKeys.size() >= p.n) - { - bool is1of2 = (p.m == 1 && p.n == 2); - CKey privKey; - - // must be a valid cc eval code - if (CCinitLite(&C, p.evalCode)) - { - // pay to cc address is a valid tx - if (!is1of2) - { - bool havePriv = creator.KeyStore().GetKey(p.vKeys[0].GetID(), privKey); - - // if we don't have the private key, it must be the unspendable address - if (!havePriv && (p.vKeys[0] == CPubKey(ParseHex(C.CChexstr)))) - { - privKey = CKey(); - std::vector vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv)); - privKey.Set(vch.begin(), vch.end(), false); - } - - CC *cc = CCcond1(p.evalCode, p.vKeys[0]); - - if (cc) - { - vector vch; - if (creator.CreateSig(vch, p.vKeys[0].GetID(), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc)) - { - ret.push_back(vch); - } - else - { - fprintf(stderr,"vin has 1of1 CC signing error with address.(%s)\n", p.vKeys[0].GetID().ToString().c_str()); - } - - cc_free(cc); - return ret.size() != 0; - } - } - else - { - // first of priv key in our key store or contract address is what we sign with - for (auto pk : p.vKeys) - { - if (creator.IsKeystoreValid() && creator.KeyStore().GetKey(pk.GetID(), privKey) && privKey.IsValid()) - break; - - if (pk == CPubKey(ParseHex(C.CChexstr))) - { - privKey = CKey(); - std::vector vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv)); - privKey.Set(vch.begin(), vch.end(), false); - break; - } - } - - if (!privKey.IsValid()) - return false; - - CC *cc = CCcond1of2(p.evalCode, p.vKeys[0], p.vKeys[1]); - - if (cc) - { - vector vch; - if (creator.CreateSig(vch, p.vKeys[0].GetID(), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc)) - { - ret.push_back(vch); - } - else - { - fprintf(stderr,"vin has 1of2 CC signing error with addresses.(%s)\n(%s)\n", p.vKeys[0].GetID().ToString().c_str(), p.vKeys[1].GetID().ToString().c_str()); - } - - cc_free(cc); - return ret.size() != 0; - } - } - } - } return false; } diff --git a/src/test-hush/test_cryptoconditions.cpp b/src/test-hush/test_cryptoconditions.cpp deleted file mode 100644 index b6cca7a86..000000000 --- a/src/test-hush/test_cryptoconditions.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -#include -#include - -#include "base58.h" -#include "key.h" -#include "script/cc.h" -#include "cc/eval.h" -#include "primitives/transaction.h" -#include "script/interpreter.h" -#include "script/serverchecker.h" - -#include "testutils.h" - - - -class CCTest : public ::testing::Test { -public: - void CCSign(CMutableTransaction &tx, CC *cond) { - tx.vin.resize(1); - PrecomputedTransactionData txdata(tx); - uint256 sighash = SignatureHash(CCPubKey(cond), tx, 0, SIGHASH_ALL, 0, 0, &txdata); - - int out = cc_signTreeSecp256k1Msg32(cond, notaryKey.begin(), sighash.begin()); - tx.vin[0].scriptSig = CCSig(cond); - } -protected: - virtual void SetUp() { - // enable CC - ASSETCHAINS_CC = 1; - } -}; - - -TEST_F(CCTest, testIsPayToCryptoCondition) -{ - CScript s = CScript() << VCH("a", 1); - ASSERT_FALSE(s.IsPayToCryptoCondition()); - - s = CScript() << VCH("a", 1) << OP_CHECKCRYPTOCONDITION; - ASSERT_TRUE(s.IsPayToCryptoCondition()); - - s = CScript() << OP_CHECKCRYPTOCONDITION; - ASSERT_FALSE(s.IsPayToCryptoCondition()); -} - - -TEST_F(CCTest, testMayAcceptCryptoCondition) -{ - CC *cond; - - // ok - CCFromJson(cond, R"!!( - { "type": "threshold-sha-256", - "threshold": 2, - "subfulfillments": [ - { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } - ] - })!!"); - ASSERT_TRUE(CCPubKey(cond).MayAcceptCryptoCondition()); - - - // prefix not allowed - CCFromJson(cond, R"!!( - { "type": "prefix-sha-256", - "prefix": "abc", - "maxMessageLength": 10, - "subfulfillment": - { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } - })!!"); - ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition()); - - - // has no signature nodes - CCFromJson(cond, R"!!( - { "type": "threshold-sha-256", - "threshold": 1, - "subfulfillments": [ - { "type": "eval-sha-256", "code": "" }, - { "type": "eval-sha-256", "code": "" } - ] - })!!"); - ASSERT_FALSE(CCPubKey(cond).MayAcceptCryptoCondition()); -} - - -static bool CCVerify(const CMutableTransaction &mtxTo, const CC *cond) { - CAmount amount; - ScriptError error; - CTransaction txTo(mtxTo); - PrecomputedTransactionData txdata(txTo); - auto checker = ServerTransactionSignatureChecker(&txTo, 0, amount, false, txdata); - return VerifyScript(CCSig(cond), CCPubKey(cond), 0, checker, 0, &error); -}; - - -TEST_F(CCTest, testVerifyCryptoCondition) -{ - CC *cond; - CMutableTransaction mtxTo; - - // ok - cond = CCNewSecp256k1(notaryKey.GetPubKey()); - CCFromJson(cond, R"!!({ - "type": "secp256k1-sha-256", - "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" - })!!"); - CCSign(mtxTo, cond); - ASSERT_TRUE(CCVerify(mtxTo, cond)); - - - // has signature nodes - CCFromJson(cond, R"!!({ - "type": "threshold-sha-256", - "threshold": 1, - "subfulfillments": [ - { "type": "preimage-sha-256", "preimage": "" }, - { "type": "secp256k1-sha-256", "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" } - ] - })!!"); - cond->threshold = 2; - CCSign(mtxTo, cond); - ASSERT_TRUE(CCVerify(mtxTo, cond)); - - // no signatures; the preimage will get encoded as a fulfillment because it's cheaper - // and the secp256k1 node will get encoded as a condition - cond->threshold = 1; - ASSERT_FALSE(CCVerify(mtxTo, cond)); - - // here the signature is set wrong - cond->threshold = 2; - ASSERT_TRUE(CCVerify(mtxTo, cond)); - memset(cond->subconditions[1]->signature, 0, 32); - ASSERT_FALSE(CCVerify(mtxTo, cond)); -} - -extern Eval* EVAL_TEST; - -TEST_F(CCTest, testVerifyEvalCondition) -{ - - class EvalMock : public Eval - { - public: - bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) - { return cond->code[0] ? Valid() : Invalid(""); } - }; - - EvalMock eval; - EVAL_TEST = &eval; - - - CC *cond; - CMutableTransaction mtxTo; - - // ok - cond = CCNewThreshold(2, { CCNewSecp256k1(notaryKey.GetPubKey()), CCNewEval({1}) }); - CCSign(mtxTo, cond); - ASSERT_TRUE(CCVerify(mtxTo, cond)); - - cond->subconditions[1]->code[0] = 0; - ASSERT_FALSE(CCVerify(mtxTo, cond)); -} - - -TEST_F(CCTest, testCryptoConditionsDisabled) -{ - CC *cond; - ScriptError error; - CMutableTransaction mtxTo; - - // ok - CCFromJson(cond, R"!!({ - "type": "secp256k1-sha-256", - "publicKey": "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47" - })!!"); - CCSign(mtxTo, cond); - ASSERT_TRUE(CCVerify(mtxTo, cond)); - - ASSETCHAINS_CC = 0; - ASSERT_FALSE(CCVerify(mtxTo, cond)); -} - - -TEST_F(CCTest, testLargeCondition) -{ - CC *cond; - ScriptError error; - CMutableTransaction mtxTo; - - std::vector ccs; - for (int i=0; i<18; i++) { - ccs.push_back(CCNewSecp256k1(notaryKey.GetPubKey())); - } - cond = CCNewThreshold(16, ccs); - CCSign(mtxTo, cond); - EXPECT_EQ("(16 of 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,A5,A5)", - CCShowStructure(CCPrune(cond))); - EXPECT_EQ(1744, CCSig(cond).size()); - ASSERT_TRUE(CCVerify(mtxTo, cond)); -} diff --git a/src/test-hush/test_eval_bet.cpp b/src/test-hush/test_eval_bet.cpp deleted file mode 100644 index ca35653c4..000000000 --- a/src/test-hush/test_eval_bet.cpp +++ /dev/null @@ -1,597 +0,0 @@ -// Copyright (c) 2016-2023 The Hush developers -// Distributed under the GPLv3 software license, see the accompanying -// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html -#include -#include -#include "cc/betprotocol.h" -#include "cc/eval.h" -#include "base58.h" -#include "key.h" -#include "main.h" -#include "script/cc.h" -#include "primitives/transaction.h" -#include "script/interpreter.h" -#include "script/serverchecker.h" -#include "testutils.h" - -extern Eval* EVAL_TEST; - -namespace TestBet { - -static std::vector playerSecrets; -static std::vector players; - -static int Dealer = 0, Player1 = 1, Player2 = 2; - - -int CCSign(CMutableTransaction &tx, unsigned int nIn, CC *cond, std::vector keyIds) { - PrecomputedTransactionData txdata(tx); - uint256 sighash = SignatureHash(CCPubKey(cond), tx, nIn, SIGHASH_ALL, 0, 0, &txdata); - int nSigned = 0; - for (int i=0; i> evaluate( - std::vector header, std::vector body) - { - std::vector outs; - if (memcmp(header.data(), "BetHeader", 9)) { - printf("Wrong VM header\n"); - return std::make_pair(0, outs); - } - outs.push_back(CTxOut(2, CScript() << OP_RETURN << body.size())); - return std::make_pair(body.size(), outs); - } -}; - -const EvalCode EVAL_DISPUTEBET = 0xf2; - -class EvalMock : public Eval -{ -public: - uint256 MoM; - int currentHeight; - std::map txs; - std::map blocks; - std::map> spends; - - bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) - { - EvalCode ecode = cond->code[0]; - std::vector vparams(cond->code+1, cond->code+cond->codeLength); - - if (ecode == EVAL_DISPUTEBET) { - MockVM vm; - return DisputePayout(vm, vparams, txTo, nIn); - } - if (ecode == EVAL_IMPORTPAYOUT) { - return ImportPayout(vparams, txTo, nIn); - } - return Invalid("invalid-code"); - } - - bool GetSpendsConfirmed(uint256 hash, std::vector &spendsOut) const - { - auto r = spends.find(hash); - if (r != spends.end()) { - spendsOut = r->second; - return true; - } - return false; - } - - bool GetTxUnconfirmed(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) const - { - auto r = txs.find(hash); - if (r != txs.end()) { - txOut = r->second; - if (blocks.count(hash) > 0) - hashBlock = hash; - return true; - } - return false; - } - - unsigned int GetCurrentHeight() const { return currentHeight; } - - bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const - { - auto r = blocks.find(hash); - if (r == blocks.end()) return false; - blockIdx = r->second; - return true; - } - - bool GetNotarizationData(uint256 notarizationHash, NotarizationData &data) const - { - if (notarizationHash == NotarizationHash()) { - data.MoM = MoM; - return true; - } - return false; - } - - static uint256 NotarizationHash() - { - uint256 h; - h.begin()[0] = 123; - return h; - } -}; - - -/* - * Generates example data that we will test with and shows how to call BetProtocol. - */ -class ExampleBet -{ -public: - BetProtocol bet; - CAmount totalPayout; - - ExampleBet() : bet(BetProtocol(EVAL_DISPUTEBET, players, 2, VCH("BetHeader", 9))), totalPayout(100) {} - ~ExampleBet() {}; - - CTransaction SessionTx() - { - return CTransaction(bet.MakeSessionTx(1)); - } - - CC* DisputeCond() - { - return bet.MakeDisputeCond(); - } - - CC* PayoutCond() - { - return bet.MakePayoutCond(SessionTx().GetHash()); - } - - CTransaction StakeTx() - { - return CTransaction(bet.MakeStakeTx(totalPayout, SessionTx().GetHash())); - } - - std::vector PlayerState(int playerIdx) - { - std::vector state; - for (int i=0; i Payouts(int playerIdx) - { - return MockVM().evaluate(bet.vmParams, PlayerState(playerIdx)).second; - } - - CMutableTransaction DisputeTx(int playerIdx) - { - return bet.MakeDisputeTx(SessionTx().GetHash(), SerializeHash(Payouts(playerIdx))); - } - - CMutableTransaction PostEvidenceTx(int playerIdx) - { - return bet.MakePostEvidenceTx(SessionTx().GetHash(), playerIdx, PlayerState(playerIdx)); - } - - CMutableTransaction AgreePayoutTx() - { - std::vector v; - return bet.MakeAgreePayoutTx(v, uint256()); - } - - MoMProof GetMoMProof() - { - int nIndex = 5; - std::vector vBranch; - vBranch.resize(3); - return {MerkleBranch(nIndex, vBranch), EvalMock::NotarizationHash()}; - } - - CMutableTransaction ImportPayoutTx() - { - CMutableTransaction disputeTx = DisputeTx(Player2); - return bet.MakeImportPayoutTx(Payouts(Player2), disputeTx, uint256(), GetMoMProof()); - } - - EvalMock SetEvalMock(int currentHeight) - { - EvalMock eval; - CTransaction sessionTx = SessionTx(); - - eval.txs[sessionTx.GetHash()] = sessionTx; - - CBlockIndex sessionBlock; - sessionBlock.SetHeight(10); - eval.blocks[sessionTx.GetHash()] = sessionBlock; - - std::vector sessionSpends; - sessionSpends.push_back(CTransaction(PostEvidenceTx(Dealer))); - sessionSpends.push_back(CTransaction()); // Invalid, should be ignored - sessionSpends.push_back(CTransaction(PostEvidenceTx(Player2))); - eval.spends[sessionTx.GetHash()] = sessionSpends; - - eval.currentHeight = currentHeight; - - MoMProof proof = GetMoMProof(); - eval.MoM = proof.branch.Exec(DisputeTx(Player2).GetHash()); - - EVAL_TEST = &eval; - return eval; - } -}; - - -ExampleBet ebet; - - -class TestBet : public ::testing::Test { -protected: - static void SetUpTestCase() { - // Make playerSecrets - CBitcoinSecret vchSecret; - auto addKey = [&] (std::string k) { vchSecret.SetString(k); playerSecrets.push_back(vchSecret.GetKey()); }; - addKey("UwFBKf4d6wC3yqdnk3LoGrFjy7gwxrWerBT8jTFamrBbem8wSw9L"); - addKey("Up6GpWwrmx2VpqF8rD3snJXToKT56Dzc8YSoL24osXnfNdCucaMR"); - addKey("UxEHwki3A95PSHHVRzE2N67eHTeoUcqLkovxp6yDPVViv54skF8c"); - // Make playerpubkeys - for (int i=0; isubconditions[0]; - uint8_t target[100]; - sprintf((char*)target, "%c\x02\tBetHeader", EVAL_DISPUTEBET); - EXPECT_EQ(0, memcmp(target, evalCond->code, 12)); - - for (int i=0; isubconditions[1]->subconditions[i])); -} - - -TEST_F(TestBet, testSignDisputeCond) -{ - // Only one key needed to dispute - CMutableTransaction disputeTx = ebet.DisputeTx(Player1); - CC *disputeCond = ebet.DisputeCond(); - EXPECT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player1})); - - EXPECT_EQ(1, cc_isFulfilled(disputeCond->subconditions[0])); - EXPECT_EQ(1, cc_isFulfilled(disputeCond->subconditions[1])); - EXPECT_EQ(0, cc_isFulfilled(disputeCond->subconditions[1]->subconditions[0])); - EXPECT_EQ(1, cc_isFulfilled(disputeCond->subconditions[1]->subconditions[1])); - EXPECT_EQ(0, cc_isFulfilled(disputeCond->subconditions[1]->subconditions[2])); - EXPECT_EQ(1, cc_isFulfilled(disputeCond)); -} - - -TEST_F(TestBet, testDispute) -{ - EvalMock eval = ebet.SetEvalMock(12); - - // Only one key needed to dispute - CMutableTransaction disputeTx = ebet.DisputeTx(Player2); - CC *disputeCond = ebet.DisputeCond(); - EXPECT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player2})); - - // Success - EXPECT_TRUE(TestCC(disputeTx, 0, disputeCond)); - - // Set result hash to 0 and check false - uint256 nonsense; - disputeTx.vout[0].scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << nonsense); - EXPECT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player2})); - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("wrong-payout", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testDisputeInvalidOutput) -{ - EvalMock eval = ebet.SetEvalMock(11); - - // Only one key needed to dispute - CMutableTransaction disputeTx = ebet.DisputeTx(Dealer); - CC *disputeCond = ebet.DisputeCond(); - - // invalid payout hash - std::vector invalidHash = {0,1,2}; - disputeTx.vout[0].scriptPubKey = CScript() << OP_RETURN << invalidHash; - ASSERT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player1})); - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("invalid-payout-hash", eval.state.GetRejectReason()); - - // no vout at all - disputeTx.vout.resize(0); - ASSERT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player1})); - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("no-vouts", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testDisputeEarly) -{ - EvalMock eval = ebet.SetEvalMock(11); - - // Only one key needed to dispute - CMutableTransaction disputeTx = ebet.DisputeTx(Dealer); - CC *disputeCond = ebet.DisputeCond(); - EXPECT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player1})); - - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("dispute-too-soon", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testDisputeInvalidParams) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction disputeTx = ebet.DisputeTx(Player2); - CC *disputeCond = ebet.DisputeCond(); - CC *evalCond = disputeCond->subconditions[0]; - - // too long - evalCond->code = (unsigned char*) realloc(evalCond->code, ++evalCond->codeLength); - ASSERT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player2})); - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("malformed-params", eval.state.GetRejectReason()); - - // too short - eval.state = CValidationState(); - evalCond->codeLength = 1; - ASSERT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player2})); - EXPECT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("malformed-params", eval.state.GetRejectReason()); - - // is fine - eval.state = CValidationState(); - evalCond->codeLength = 12; - ASSERT_EQ(1, CCSign(disputeTx, 0, disputeCond, {Player2})); - EXPECT_TRUE(TestCC(disputeTx, 0, disputeCond)); -} - - -TEST_F(TestBet, testDisputeInvalidEvidence) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction disputeTx = ebet.DisputeTx(Player2); - CC *disputeCond = ebet.DisputeCond(); - CCSign(disputeTx, 0, disputeCond, {Player2}); - - CMutableTransaction mtx; - - mtx.vout.resize(1); - mtx.vout[0].scriptPubKey = CScript(); - eval.spends[ebet.SessionTx().GetHash()][1] = CTransaction(mtx); - ASSERT_TRUE(TestCC(disputeTx, 0, disputeCond)); - - mtx.vout[0].scriptPubKey << OP_RETURN; - eval.spends[ebet.SessionTx().GetHash()][1] = CTransaction(mtx); - ASSERT_TRUE(TestCC(disputeTx, 0, disputeCond)); - - mtx.vout[0].scriptPubKey = CScript() << 0; - eval.spends[ebet.SessionTx().GetHash()][1] = CTransaction(mtx); - ASSERT_TRUE(TestCC(disputeTx, 0, disputeCond)); - - eval.spends[ebet.SessionTx().GetHash()].resize(1); - eval.spends[ebet.SessionTx().GetHash()][0] = CTransaction(); - ASSERT_FALSE(TestCC(disputeTx, 0, disputeCond)); - EXPECT_EQ("no-evidence", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testMakeStakeTx) -{ - CTransaction stakeTx = ebet.StakeTx(); - EXPECT_EQ(0, stakeTx.vin.size()); - EXPECT_EQ(1, stakeTx.vout.size()); - EXPECT_EQ(ebet.totalPayout, stakeTx.vout[0].nValue); - EXPECT_EQ(CCPubKey(ebet.PayoutCond()), stakeTx.vout[0].scriptPubKey); -} - - -TEST_F(TestBet, testMakePayoutCond) -{ - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ("(1 of (3 of 5,5,5),(2 of (1 of 5,5,5),15))", CCShowStructure(payoutCond)); - EXPECT_EQ(0, memcmp(payoutCond->subconditions[1]->subconditions[1]->code+1, - ebet.SessionTx().GetHash().begin(), 32)); -} - - -TEST_F(TestBet, testSignPayout) -{ - - CMutableTransaction payoutTx = ebet.AgreePayoutTx(); - CC *payoutCond = ebet.PayoutCond(); - - EXPECT_EQ(0, cc_isFulfilled(payoutCond->subconditions[0])); - EXPECT_EQ(0, cc_isFulfilled(payoutCond->subconditions[1])); - EXPECT_EQ(0, cc_isFulfilled(payoutCond)); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Player1})); - EXPECT_EQ(0, cc_isFulfilled(payoutCond->subconditions[0])); - EXPECT_EQ(1, cc_isFulfilled(payoutCond->subconditions[1])); - EXPECT_EQ(1, cc_isFulfilled(payoutCond)); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Player2})); - EXPECT_EQ(0, cc_isFulfilled(payoutCond->subconditions[0])); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Dealer})); - EXPECT_EQ(1, cc_isFulfilled(payoutCond->subconditions[0])); -} - - -TEST_F(TestBet, testAgreePayout) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction payoutTx = ebet.AgreePayoutTx(); - CC *payoutCond = ebet.PayoutCond(); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Dealer})); - EXPECT_FALSE(TestCC(payoutTx, 0, payoutCond)); - EXPECT_EQ("(1 of (2 of (1 of 5,A5,A5),15),A2)", - CCShowStructure(CCPrune(payoutCond))); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Player1})); - EXPECT_FALSE(TestCC(payoutTx, 0, payoutCond)); - EXPECT_EQ("(1 of (2 of (1 of 5,A5,A5),15),A2)", - CCShowStructure(CCPrune(payoutCond))); - - EXPECT_EQ(2, CCSign(payoutTx, 0, payoutCond, {Player2})); - EXPECT_TRUE( TestCC(payoutTx, 0, payoutCond)); - EXPECT_EQ("(1 of (3 of 5,5,5),A2)", - CCShowStructure(CCPrune(payoutCond))); -} - - -TEST_F(TestBet, testImportPayout) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction importTx = ebet.ImportPayoutTx(); - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - EXPECT_TRUE(TestCC(importTx, 0, payoutCond)); -} - - -TEST_F(TestBet, testImportPayoutFewVouts) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction importTx = ebet.ImportPayoutTx(); - importTx.vout.resize(0); - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - EXPECT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("no-vouts", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testImportPayoutInvalidPayload) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction importTx = ebet.ImportPayoutTx(); - importTx.vout[0].scriptPubKey.pop_back(); - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - EXPECT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("invalid-payload", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testImportPayoutWrongPayouts) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction importTx = ebet.ImportPayoutTx(); - importTx.vout[1].nValue = 7; - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - ASSERT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("wrong-payouts", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testImportPayoutMangleSessionId) -{ - EvalMock eval = ebet.SetEvalMock(12); - - CMutableTransaction importTx = ebet.ImportPayoutTx(); - CC *payoutCond = ebet.PayoutCond(); - payoutCond->subconditions[1]->subconditions[1]->codeLength = 31; - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - ASSERT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("malformed-params", eval.state.GetRejectReason()); - - payoutCond = ebet.PayoutCond(); - memset(payoutCond->subconditions[1]->subconditions[1]->code+1, 1, 32); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - ASSERT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("wrong-session", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testImportPayoutInvalidNotarizationHash) -{ - EvalMock eval = ebet.SetEvalMock(12); - - MoMProof proof = ebet.GetMoMProof(); - proof.notarizationHash = uint256(); - CMutableTransaction importTx = ebet.bet.MakeImportPayoutTx( - ebet.Payouts(Player2), ebet.DisputeTx(Player2), uint256(), proof); - - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - EXPECT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("coudnt-load-mom", eval.state.GetRejectReason()); -} - - -TEST_F(TestBet, testImportPayoutMomFail) -{ - EvalMock eval = ebet.SetEvalMock(12); - - MoMProof proof = ebet.GetMoMProof(); - proof.branch.nIndex ^= 1; - CMutableTransaction importTx = ebet.bet.MakeImportPayoutTx( - ebet.Payouts(Player2), ebet.DisputeTx(Player2), uint256(), proof); - - CC *payoutCond = ebet.PayoutCond(); - EXPECT_EQ(2, CCSign(importTx, 0, payoutCond, {Player2})); - EXPECT_FALSE(TestCC(importTx, 0, payoutCond)); - EXPECT_EQ("mom-check-fail", eval.state.GetRejectReason()); -} - - -} /* namespace TestBet */