tests for getting MoM in Eval and fixes
This commit is contained in:
@@ -6,7 +6,8 @@ bin_PROGRAMS += komodo-test
|
||||
komodo_test_SOURCES = \
|
||||
test-komodo/main.cpp \
|
||||
test-komodo/test_cryptoconditions.cpp \
|
||||
test-komodo/test_bet.cpp
|
||||
test-komodo/test_eval_bet.cpp \
|
||||
test-komodo/test_eval_notarisation.cpp
|
||||
|
||||
komodo_test_CPPFLAGS = $(komodod_CPPFLAGS)
|
||||
|
||||
|
||||
@@ -7,44 +7,6 @@
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
|
||||
static unsigned char* CopyPubKey(CPubKey pkIn)
|
||||
{
|
||||
unsigned char* pk = (unsigned char*) malloc(33);
|
||||
memcpy(pk, pkIn.begin(), 33); // TODO: compressed?
|
||||
return pk;
|
||||
}
|
||||
|
||||
|
||||
CC* CCNewThreshold(int t, std::vector<CC*> 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::string method, std::vector<unsigned char> paramsBin)
|
||||
{
|
||||
CC *cond = cc_new(CC_Eval);
|
||||
strcpy(cond->method, method.data());
|
||||
cond->paramsBin = (unsigned char*) malloc(paramsBin.size());
|
||||
memcpy(cond->paramsBin, paramsBin.data(), paramsBin.size());
|
||||
cond->paramsBinLength = paramsBin.size();
|
||||
return cond;
|
||||
}
|
||||
|
||||
|
||||
std::vector<CC*> BetProtocol::PlayerConditions()
|
||||
{
|
||||
std::vector<CC*> subs;
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
#define BETPROTOCOL_H
|
||||
|
||||
#include "pubkey.h"
|
||||
#include "primitives/block.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "cryptoconditions/include/cryptoconditions.h"
|
||||
|
||||
|
||||
#define ExecMerkle CBlock::CheckMerkleBranch
|
||||
|
||||
|
||||
class MoMProof
|
||||
{
|
||||
public:
|
||||
@@ -18,6 +16,7 @@ public:
|
||||
|
||||
MoMProof() {}
|
||||
MoMProof(int i, std::vector<uint256> b, uint256 n) : notarisationHash(n), nIndex(i), branch(b) {}
|
||||
uint256 Exec(uint256 hash) const { return CBlock::CheckMerkleBranch(hash, branch, nIndex); }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
@@ -79,7 +78,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
CC* CCNewSecp256k1(CPubKey k);
|
||||
|
||||
|
||||
#endif /* BETPROTOCOL_H */
|
||||
|
||||
@@ -88,14 +88,19 @@ bool Eval::GetBlock(uint256 hash, CBlockIndex& blockIdx) const
|
||||
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
|
||||
|
||||
int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
|
||||
{
|
||||
return komodo_notaries(pubkeys, height, timestamp);
|
||||
}
|
||||
|
||||
|
||||
bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
|
||||
{
|
||||
if (tx.vin.size() < 11) return false;
|
||||
|
||||
uint8_t seenNotaries[64] = {0};
|
||||
uint8_t notaries[64][33];
|
||||
uint8_t seenNotaries[64];
|
||||
int nNotaries = komodo_notaries(notaries, height, timestamp);
|
||||
char pk[33];
|
||||
int nNotaries = GetNotaries(notaries, height, timestamp);
|
||||
|
||||
BOOST_FOREACH(const CTxIn &txIn, tx.vin)
|
||||
{
|
||||
@@ -104,10 +109,11 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t
|
||||
uint256 hashBlock;
|
||||
if (!GetTx(txIn.prevout.hash, tx, hashBlock, false)) return false;
|
||||
if (tx.vout.size() < txIn.prevout.n) return false;
|
||||
const unsigned char *script = tx.vout[txIn.prevout.n].scriptPubKey.data();
|
||||
if (script[0] != 33) return false;
|
||||
memcpy(pk, script+1, 33);
|
||||
return true;
|
||||
CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
|
||||
if (spk.size() != 35) return false;
|
||||
const unsigned char *pk = spk.data();
|
||||
if (pk++[0] != 33) return false;
|
||||
if (pk[33] != OP_CHECKSIG) return false;
|
||||
|
||||
// Check it's a notary
|
||||
for (int i=0; i<nNotaries; i++) {
|
||||
@@ -121,31 +127,51 @@ bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t t
|
||||
return false;
|
||||
found:;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NotarisationData::Parse(const CScript scriptPK)
|
||||
{
|
||||
*this = NotarisationData();
|
||||
|
||||
std::vector<unsigned char> vdata;
|
||||
if (!GetOpReturnData(scriptPK, vdata)) return false;
|
||||
|
||||
CDataStream ss(vdata, SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
try {
|
||||
ss >> blockHash;
|
||||
ss >> height;
|
||||
|
||||
char *nullPos = (char*) memchr(&ss[0], 0, ss.size());
|
||||
if (!nullPos) return false;
|
||||
ss.read(symbol, nullPos-&ss[0]+1);
|
||||
|
||||
if (ss.size() != 36) return false;
|
||||
ss >> MoM;
|
||||
ss >> MoMDepth;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get MoM from a notarisation tx hash
|
||||
*/
|
||||
bool Eval::GetMoM(const uint256 notaryHash, uint256 &mom) const
|
||||
bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) const
|
||||
{
|
||||
CTransaction notarisationTx;
|
||||
uint256 notarisationBlock;
|
||||
if (!GetTx(notaryHash, notarisationTx, notarisationBlock, true)) return 0;
|
||||
if (!GetTx(notaryHash, notarisationTx, notarisationBlock, true)) return false;
|
||||
CBlockIndex block;
|
||||
if (!GetBlock(notarisationBlock, block)) return 0;
|
||||
if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.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;
|
||||
if (!GetBlock(notarisationBlock, block)) return false;
|
||||
if (!CheckNotaryInputs(notarisationTx, block.nHeight, block.nTime)) return false;
|
||||
if (notarisationTx.vout.size() < 2) return false;
|
||||
if (!data.Parse(notarisationTx.vout[1].scriptPubKey)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
class AppVM;
|
||||
class NotarisationData;
|
||||
|
||||
|
||||
class Eval
|
||||
@@ -44,7 +45,8 @@ public:
|
||||
virtual unsigned int GetCurrentHeight() const;
|
||||
virtual bool GetSpends(uint256 hash, std::vector<CTransaction> &spends) const;
|
||||
virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const;
|
||||
virtual bool GetMoM(uint256 notarisationHash, uint256& MoM) const;
|
||||
virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const;
|
||||
virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const;
|
||||
virtual bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const;
|
||||
};
|
||||
|
||||
@@ -69,16 +71,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Data from notarisation OP_RETURN
|
||||
*/
|
||||
class NotarisationData {
|
||||
public:
|
||||
uint256 blockHash;
|
||||
uint32_t height;
|
||||
uint256 txHash;
|
||||
char symbol[64];
|
||||
uint256 MoM;
|
||||
uint32_t MoMDepth;
|
||||
|
||||
bool Parse(CScript scriptPubKey);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Serialisation boilerplate
|
||||
*/
|
||||
template <class T>
|
||||
std::vector<unsigned char> CheckSerialize(T &in);
|
||||
template <class T>
|
||||
bool CheckDeserialize(std::vector<unsigned char> vIn, T &out);
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
std::vector<unsigned char> CheckSerialize(T &in)
|
||||
{
|
||||
@@ -87,7 +98,6 @@ std::vector<unsigned char> CheckSerialize(T &in)
|
||||
return std::vector<unsigned char>(ss.begin(), ss.end());
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
bool CheckDeserialize(std::vector<unsigned char> vIn, T &out)
|
||||
{
|
||||
|
||||
@@ -69,10 +69,10 @@ bool Eval::ImportPayout(const CC *cond, const CTransaction &payoutTx, unsigned i
|
||||
if (!CheckDeserialize(vProof, proof))
|
||||
return Invalid("invalid-mom-proof-payload");
|
||||
|
||||
uint256 MoM;
|
||||
if (!GetMoM(proof.notarisationHash, MoM)) return Invalid("coudnt-load-mom");
|
||||
NotarisationData data;
|
||||
if (!GetNotarisationData(proof.notarisationHash, data)) return Invalid("coudnt-load-mom");
|
||||
|
||||
if (MoM != ExecMerkle(disputeTx.GetHash(), proof.branch, proof.nIndex))
|
||||
if (data.MoM != proof.Exec(disputeTx.GetHash()))
|
||||
return Invalid("mom-check-fail");
|
||||
}
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ UniValue txMoMproof(const UniValue& params, bool fHelp)
|
||||
if ( fHelp || params.size() != 1)
|
||||
throw runtime_error("txmomproof needs a txid");
|
||||
|
||||
uint256 hash(uint256S(params[0].get_str()));
|
||||
hash = uint256S(params[0].get_str());
|
||||
|
||||
uint256 blockHash;
|
||||
CTransaction tx;
|
||||
@@ -666,6 +666,10 @@ UniValue txMoMproof(const UniValue& params, bool fHelp)
|
||||
fakeBlock.vtx.push_back(fakeTx);
|
||||
}
|
||||
branch = fakeBlock.GetMerkleBranch(nIndex);
|
||||
|
||||
// Check branch
|
||||
if (MoM != CBlock::CheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed merkle block->MoM");
|
||||
}
|
||||
|
||||
// Now get the tx merkle branch
|
||||
@@ -687,12 +691,21 @@ UniValue txMoMproof(const UniValue& params, bool fHelp)
|
||||
if (nTxIndex == (int)block.vtx.size())
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error locating tx in block");
|
||||
|
||||
// concatenate branches
|
||||
std::vector<uint256> txBranch = block.GetMerkleBranch(nTxIndex);
|
||||
nIndex = nIndex << txBranch.size() + nTxIndex;
|
||||
|
||||
// Check branch
|
||||
if (block.hashMerkleRoot != CBlock::CheckMerkleBranch(hash, txBranch, nTxIndex))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed merkle tx->block");
|
||||
|
||||
// concatenate branches
|
||||
nIndex = (nIndex << txBranch.size()) + nTxIndex;
|
||||
branch.insert(branch.begin(), txBranch.begin(), txBranch.end());
|
||||
}
|
||||
|
||||
// Check the proof
|
||||
if (MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed validating MoM");
|
||||
|
||||
// Encode and return
|
||||
CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssProof << MoMProof(nIndex, branch, notarisationHash);
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
extern Eval* EVAL_TEST;
|
||||
|
||||
|
||||
namespace TestBet {
|
||||
|
||||
|
||||
static std::vector<CKey> playerSecrets;
|
||||
static std::vector<CPubKey> players;
|
||||
@@ -72,7 +77,7 @@ public:
|
||||
std::map<uint256, CBlockIndex> blocks;
|
||||
std::map<uint256, std::vector<CTransaction>> spends;
|
||||
|
||||
bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
|
||||
bool Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
|
||||
{
|
||||
if (strcmp(cond->method, "DisputeBet") == 0) {
|
||||
MockVM vm;
|
||||
@@ -115,10 +120,10 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetMoM(uint256 notarisationHash, uint256& _MoM) const
|
||||
bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const
|
||||
{
|
||||
if (notarisationHash == NotarisationHash()) {
|
||||
_MoM = MoM;
|
||||
data.MoM = MoM;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -133,9 +138,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
extern Eval* EVAL_TEST;
|
||||
|
||||
|
||||
/*
|
||||
* Generates example data that we will test with and shows how to call BetProtocol.
|
||||
*/
|
||||
@@ -230,7 +232,7 @@ public:
|
||||
eval.currentHeight = currentHeight;
|
||||
|
||||
MoMProof proof = GetMoMProof();
|
||||
eval.MoM = ExecMerkle(DisputeTx(Player2).GetHash(), proof.branch, proof.nIndex);
|
||||
eval.MoM = proof.Exec(DisputeTx(Player2).GetHash());
|
||||
|
||||
EVAL_TEST = &eval;
|
||||
return eval;
|
||||
@@ -594,3 +596,6 @@ TEST_F(TestBet, testImportPayoutMomFail)
|
||||
EXPECT_FALSE(TestCC(importTx, 0, payoutCond));
|
||||
EXPECT_EQ("mom-check-fail", eval.state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
} /* namespace TestBet */
|
||||
203
src/test-komodo/test_eval_notarisation.cpp
Normal file
203
src/test-komodo/test_eval_notarisation.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include <cryptoconditions.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "cc/betprotocol.h"
|
||||
#include "cc/eval.h"
|
||||
#include "base58.h"
|
||||
#include "core_io.h"
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
#include "komodo_cc.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/interpreter.h"
|
||||
#include "script/serverchecker.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
extern Eval* EVAL_TEST;
|
||||
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
|
||||
|
||||
namespace TestEvalNotarisation {
|
||||
|
||||
|
||||
class EvalMock : public Eval
|
||||
{
|
||||
public:
|
||||
uint32_t nNotaries;
|
||||
uint8_t notaries[64][33];
|
||||
std::map<uint256, CTransaction> txs;
|
||||
std::map<uint256, CBlockIndex> blocks;
|
||||
|
||||
int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const
|
||||
{
|
||||
memcpy(pubkeys, notaries, sizeof(notaries));
|
||||
return nNotaries;
|
||||
}
|
||||
|
||||
bool GetTx(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) const
|
||||
{
|
||||
auto r = txs.find(hash);
|
||||
if (r != txs.end()) {
|
||||
txOut = r->second;
|
||||
hashBlock = hash;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const
|
||||
{
|
||||
auto r = blocks.find(hash);
|
||||
if (r == blocks.end()) return false;
|
||||
blockIdx = r->second;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static auto noop = [&](CMutableTransaction &mtx){};
|
||||
|
||||
|
||||
template<typename Modifier>
|
||||
void SetEval(EvalMock &eval, CMutableTransaction ¬ary, Modifier modify)
|
||||
{
|
||||
eval.nNotaries = komodo_notaries(eval.notaries, 780060, 1522946781);
|
||||
|
||||
// make fake notary inputs
|
||||
notary.vin.resize(11);
|
||||
for (int i=0; i<notary.vin.size(); i++) {
|
||||
CMutableTransaction txIn;
|
||||
txIn.vout.resize(1);
|
||||
txIn.vout[0].scriptPubKey << VCH(eval.notaries[i*2], 33) << OP_CHECKSIG;
|
||||
notary.vin[i].prevout = COutPoint(txIn.GetHash(), 0);
|
||||
eval.txs[txIn.GetHash()] = CTransaction(txIn);
|
||||
}
|
||||
|
||||
modify(notary);
|
||||
|
||||
eval.txs[notary.GetHash()] = CTransaction(notary);
|
||||
eval.blocks[notary.GetHash()].nHeight = 780060;
|
||||
eval.blocks[notary.GetHash()].nTime = 1522946781;
|
||||
|
||||
EVAL_TEST = &eval;
|
||||
}
|
||||
|
||||
|
||||
// https://kmd.explorer.supernet.org/tx/5b8055d37cff745a404d1ae45e21ffdba62da7b28ed6533c67468d7379b20bae
|
||||
// inputs have been dropped
|
||||
static auto rawNotaryTx = "01000000000290460100000000002321020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9ac0000000000000000506a4c4dae8e0f3e6e5de498a072f5967f3c418c4faba5d56ac8ce17f472d029ef3000008f2e0100424f545300050ba773f0bc31da5839fc7cb9bd7b87f3b765ca608e5cf66785a466659b28880500000000000000";
|
||||
CTransaction notaryTx;
|
||||
static bool init = DecodeHexTx(notaryTx, rawNotaryTx);
|
||||
|
||||
static uint256 proofTxHash = uint256S("37f76551a16093fbb0a92ee635bbd45b3460da8fd00cf7d5a6b20d93e727fe4c");
|
||||
static auto vMomProof = ParseHex("0303faecbdd4b3da128c2cd2701bb143820a967069375b2ec5b612f39bbfe78a8611978871c193457ab1e21b9520f4139f113b8d75892eb93ee247c18bccfd067efed7eacbfcdc8946cf22de45ad536ec0719034fb9bc825048fe6ab61fee5bd6e9aae0bb279738d46673c53d68eb2a72da6dbff215ee41a4d405a74ff7cd355805b"); // $ fiat/bots txMoMproof $proofTxHash
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testGetNotarisation)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
SetEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_TRUE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
EXPECT_EQ(data.height, 77455);
|
||||
EXPECT_EQ(data.blockHash.GetHex(), "000030ef29d072f417cec86ad5a5ab4f8c413c7f96f572a098e45d6e3e0f8eae");
|
||||
EXPECT_STREQ(data.symbol, "BOTS");
|
||||
EXPECT_EQ(data.MoMDepth, 5);
|
||||
EXPECT_EQ(data.MoM.GetHex(), "88289b6566a48567f65c8e60ca65b7f3877bbdb97cfc3958da31bcf073a70b05");
|
||||
|
||||
MoMProof proof;
|
||||
CheckDeserialize(vMomProof, proof);
|
||||
EXPECT_EQ(data.MoM, proof.Exec(proofTxHash));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotaryPubkey)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
SetEval(eval, notary, noop);
|
||||
|
||||
memset(eval.notaries[10], 0, 33);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationBadOpReturn)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
notary.vout[1].scriptPubKey = CScript() << OP_RETURN << 0;
|
||||
SetEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationTxNotEnoughSigs)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
tx.vin.resize(10);
|
||||
});
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationTxDoesntExist)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(uint256(), data));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationDupeNotary)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
tx.vin[1] = tx.vin[3];
|
||||
});
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationInputNotCheckSig)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [&](CMutableTransaction &tx) {
|
||||
int i = 1;
|
||||
CMutableTransaction txIn;
|
||||
txIn.vout.resize(1);
|
||||
txIn.vout[0].scriptPubKey << VCH(eval.notaries[i*2], 33) << OP_RETURN;
|
||||
notary.vin[i].prevout = COutPoint(txIn.GetHash(), 0);
|
||||
eval.txs[txIn.GetHash()] = CTransaction(txIn);
|
||||
});
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
|
||||
|
||||
|
||||
} /* namespace TestEvalNotarisation */
|
||||
Reference in New Issue
Block a user