wip
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#include "key.h"
|
||||
#include "base58.h"
|
||||
#include "chainparams.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "crypto/common.h"
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@@ -9,6 +11,11 @@ int main(int argc, char **argv) {
|
||||
ECC_Start();
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
|
||||
CBitcoinSecret vchSecret;
|
||||
// this returns false due to network prefix mismatch but works anyway
|
||||
vchSecret.SetString(notarySecret);
|
||||
notaryKey = vchSecret.GetKey();
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
206
src/test-komodo/test_coinimport.cpp
Normal file
206
src/test-komodo/test_coinimport.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
|
||||
#include <cryptoconditions.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "cc/importcoin.h"
|
||||
#include "cc/eval.h"
|
||||
#include "base58.h"
|
||||
#include "core_io.h"
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
#include "script/cc.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/interpreter.h"
|
||||
#include "script/serverchecker.h"
|
||||
#include "txmempool.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
extern Eval* EVAL_TEST;
|
||||
|
||||
namespace TestCoinImport {
|
||||
|
||||
|
||||
static uint8_t testNum = 0;
|
||||
|
||||
class TestCoinImport : public ::testing::Test, public Eval {
|
||||
public:
|
||||
CMutableTransaction burnTx;
|
||||
std::vector<CTxOut> payouts;
|
||||
MomoProof proof;
|
||||
uint256 MoMoM;
|
||||
CMutableTransaction importTx;
|
||||
uint32_t chainId = 2;
|
||||
CAmount amount = 100;
|
||||
|
||||
void SetImportTx() {
|
||||
CTxOut burnOutput = MakeBurnOutput(amount, chainId, payouts);
|
||||
burnTx.vout.push_back(burnOutput);
|
||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||
importTx = CMutableTransaction(MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts));
|
||||
}
|
||||
|
||||
uint32_t GetCurrentLedgerID() const { return chainId; }
|
||||
|
||||
bool GetNotarisationData(int notarisationHeight, NotarisationData &data, bool verifyCanonical) const
|
||||
{
|
||||
if (MoMoM.IsNull()) return false;
|
||||
data.MoMoM = MoMoM;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
static void SetUpTestCase() { setupChain(); }
|
||||
virtual void SetUp() {
|
||||
ASSETCHAINS_CC = 1;
|
||||
EVAL_TEST = this;
|
||||
|
||||
std::vector<uint8_t> fakepk;
|
||||
fakepk.resize(33);
|
||||
fakepk.begin()[0] = testNum++;
|
||||
payouts.push_back(CTxOut(amount, CScript() << fakepk << OP_CHECKSIG));
|
||||
SetImportTx();
|
||||
}
|
||||
|
||||
|
||||
void TestRunCCEval(CMutableTransaction mtx)
|
||||
{
|
||||
CTransaction importTx(mtx);
|
||||
PrecomputedTransactionData txdata(importTx);
|
||||
ServerTransactionSignatureChecker checker(&importTx, 0, 0, false, txdata);
|
||||
CValidationState verifystate;
|
||||
if (!VerifyCoinImport(importTx.vin[0].scriptSig, checker, verifystate))
|
||||
printf("TestRunCCEval: %s\n", verifystate.GetRejectReason().data());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testProcessImportThroughPipeline)
|
||||
{
|
||||
CValidationState mainstate;
|
||||
CTransaction tx(importTx);
|
||||
|
||||
// first should work
|
||||
acceptTxFail(tx);
|
||||
|
||||
// should fail in mempool
|
||||
ASSERT_FALSE(acceptTx(tx, mainstate));
|
||||
EXPECT_EQ("already in mempool", mainstate.GetRejectReason());
|
||||
|
||||
// should fail in persisted UTXO set
|
||||
generateBlock();
|
||||
ASSERT_FALSE(acceptTx(tx, mainstate));
|
||||
EXPECT_EQ("already have coins", mainstate.GetRejectReason());
|
||||
ASSERT_TRUE(pcoinsTip->HaveCoins(tx.GetHash()));
|
||||
|
||||
// Now disconnect the block
|
||||
CValidationState invalstate;
|
||||
if (!InvalidateBlock(invalstate, chainActive.Tip())) {
|
||||
FAIL() << invalstate.GetRejectReason();
|
||||
}
|
||||
ASSERT_FALSE(pcoinsTip->HaveCoins(tx.GetHash()));
|
||||
|
||||
// should be back in mempool
|
||||
ASSERT_FALSE(acceptTx(tx, mainstate));
|
||||
EXPECT_EQ("already in mempool", mainstate.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testNoVouts)
|
||||
{
|
||||
importTx.vout.resize(0);
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("no-vouts", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testInvalidParams)
|
||||
{
|
||||
std::vector<uint8_t> payload = E_MARSHAL(ss << EVAL_IMPORTCOIN; ss << 'a');
|
||||
importTx.vin[0].scriptSig = CScript() << payload;
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("invalid-params", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testNonCanonical)
|
||||
{
|
||||
importTx.nLockTime = 10;
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("non-canonical", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testInvalidBurnOutputs)
|
||||
{
|
||||
burnTx.vout.resize(0);
|
||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
||||
TestRunCCEval(tx);
|
||||
EXPECT_EQ("invalid-burn-outputs", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testInvalidBurnParams)
|
||||
{
|
||||
burnTx.vout[0].scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << VARINT(chainId));
|
||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
||||
TestRunCCEval(tx);
|
||||
EXPECT_EQ("invalid-burn-params", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testWrongChainId)
|
||||
{
|
||||
chainId = 0;
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("importcoin-wrong-chain", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testInvalidBurnAmount)
|
||||
{
|
||||
burnTx.vout[0].nValue = 0;
|
||||
MoMoM = burnTx.GetHash(); // TODO: an actual branch
|
||||
CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts);
|
||||
TestRunCCEval(tx);
|
||||
EXPECT_EQ("invalid-burn-amount", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testPayoutTooHigh)
|
||||
{
|
||||
importTx.vout[0].nValue = 101;
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("payout-too-high", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testInvalidPayouts)
|
||||
{
|
||||
importTx.vout[0].nValue = 40;
|
||||
importTx.vout.push_back(importTx.vout[0]);
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("wrong-payouts", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testCouldntLoadMomom)
|
||||
{
|
||||
MoMoM.SetNull();
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("coudnt-load-momom", state.GetRejectReason());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestCoinImport, testMomomCheckFail)
|
||||
{
|
||||
MoMoM.SetNull();
|
||||
MoMoM.begin()[0] = 1;
|
||||
TestRunCCEval(importTx);
|
||||
EXPECT_EQ("momom-check-fail", state.GetRejectReason());
|
||||
}
|
||||
|
||||
} /* namespace TestCoinImport */
|
||||
@@ -12,11 +12,6 @@
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
CKey notaryKey;
|
||||
|
||||
std::string pubkey = "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47";
|
||||
std::string secret = "UxFWWxsf1d7w7K5TvAWSkeX4H95XQKwdwGv49DXwWUTzPTTjHBbU";
|
||||
|
||||
|
||||
class CCTest : public ::testing::Test {
|
||||
public:
|
||||
@@ -32,11 +27,6 @@ protected:
|
||||
virtual void SetUp() {
|
||||
// enable CC
|
||||
ASSETCHAINS_CC = 1;
|
||||
// Notary key
|
||||
CBitcoinSecret vchSecret;
|
||||
// this returns false due to network prefix mismatch but works anyway
|
||||
vchSecret.SetString(secret);
|
||||
notaryKey = vchSecret.GetKey();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ public:
|
||||
int nIndex = 5;
|
||||
std::vector<uint256> vBranch;
|
||||
vBranch.resize(3);
|
||||
return MoMProof(nIndex, vBranch, EvalMock::NotarisationHash());
|
||||
return {MerkleBranch(nIndex, vBranch), EvalMock::NotarisationHash()};
|
||||
}
|
||||
|
||||
CMutableTransaction ImportPayoutTx()
|
||||
@@ -237,7 +237,7 @@ public:
|
||||
eval.currentHeight = currentHeight;
|
||||
|
||||
MoMProof proof = GetMoMProof();
|
||||
eval.MoM = proof.Exec(DisputeTx(Player2).GetHash());
|
||||
eval.MoM = proof.branch.Exec(DisputeTx(Player2).GetHash());
|
||||
|
||||
EVAL_TEST = &eval;
|
||||
return eval;
|
||||
@@ -585,7 +585,7 @@ TEST_F(TestBet, testImportPayoutMomFail)
|
||||
EvalMock eval = ebet.SetEvalMock(12);
|
||||
|
||||
MoMProof proof = ebet.GetMoMProof();
|
||||
proof.nIndex ^= 1;
|
||||
proof.branch.nIndex ^= 1;
|
||||
CMutableTransaction importTx = ebet.bet.MakeImportPayoutTx(
|
||||
ebet.Payouts(Player2), ebet.DisputeTx(Player2), uint256(), proof);
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
extern Eval* EVAL_TEST;
|
||||
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
|
||||
|
||||
|
||||
@@ -61,7 +60,7 @@ static auto noop = [&](CMutableTransaction &mtx){};
|
||||
|
||||
|
||||
template<typename Modifier>
|
||||
void SetEval(EvalMock &eval, CMutableTransaction ¬ary, Modifier modify)
|
||||
void SetupEval(EvalMock &eval, CMutableTransaction ¬ary, Modifier modify)
|
||||
{
|
||||
eval.nNotaries = komodo_notaries(eval.notaries, 780060, 1522946781);
|
||||
|
||||
@@ -80,8 +79,6 @@ void SetEval(EvalMock &eval, CMutableTransaction ¬ary, Modifier modify)
|
||||
eval.txs[notary.GetHash()] = CTransaction(notary);
|
||||
eval.blocks[notary.GetHash()].nHeight = 780060;
|
||||
eval.blocks[notary.GetHash()].nTime = 1522946781;
|
||||
|
||||
EVAL_TEST = &eval;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,12 +91,12 @@ 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);
|
||||
SetupEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_TRUE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
@@ -111,7 +108,7 @@ TEST(TestEvalNotarisation, testGetNotarisation)
|
||||
|
||||
MoMProof proof;
|
||||
E_UNMARSHAL(vMomProof, ss >> proof);
|
||||
EXPECT_EQ(data.MoM, proof.Exec(proofTxHash));
|
||||
EXPECT_EQ(data.MoM, proof.branch.Exec(proofTxHash));
|
||||
}
|
||||
|
||||
|
||||
@@ -119,13 +116,14 @@ TEST(TestEvalNotarisation, testInvalidNotaryPubkey)
|
||||
{
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
SetEval(eval, notary, noop);
|
||||
SetupEval(eval, notary, noop);
|
||||
|
||||
memset(eval.notaries[10], 0, 33);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
TEST(TestEvalNotarisation, testInvalidNotarisationBadOpReturn)
|
||||
@@ -134,7 +132,7 @@ TEST(TestEvalNotarisation, testInvalidNotarisationBadOpReturn)
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
notary.vout[1].scriptPubKey = CScript() << OP_RETURN << 0;
|
||||
SetEval(eval, notary, noop);
|
||||
SetupEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(notary.GetHash(), data));
|
||||
@@ -146,7 +144,7 @@ TEST(TestEvalNotarisation, testInvalidNotarisationTxNotEnoughSigs)
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
SetupEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
tx.vin.resize(10);
|
||||
});
|
||||
|
||||
@@ -160,7 +158,7 @@ TEST(TestEvalNotarisation, testInvalidNotarisationTxDoesntExist)
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, noop);
|
||||
SetupEval(eval, notary, noop);
|
||||
|
||||
NotarisationData data;
|
||||
ASSERT_FALSE(eval.GetNotarisationData(uint256(), data));
|
||||
@@ -172,7 +170,7 @@ TEST(TestEvalNotarisation, testInvalidNotarisationDupeNotary)
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
SetupEval(eval, notary, [](CMutableTransaction &tx) {
|
||||
tx.vin[1] = tx.vin[3];
|
||||
});
|
||||
|
||||
@@ -186,7 +184,7 @@ TEST(TestEvalNotarisation, testInvalidNotarisationInputNotCheckSig)
|
||||
EvalMock eval;
|
||||
CMutableTransaction notary(notaryTx);
|
||||
|
||||
SetEval(eval, notary, [&](CMutableTransaction &tx) {
|
||||
SetupEval(eval, notary, [&](CMutableTransaction &tx) {
|
||||
int i = 1;
|
||||
CMutableTransaction txIn;
|
||||
txIn.vout.resize(1);
|
||||
|
||||
129
src/test-komodo/testutils.cpp
Normal file
129
src/test-komodo/testutils.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <cryptoconditions.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "core_io.h"
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
#include "miner.h"
|
||||
#include "random.h"
|
||||
#include "rpcserver.h"
|
||||
#include "rpcprotocol.h"
|
||||
#include "txdb.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "utiltime.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/cc.h"
|
||||
#include "script/interpreter.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
|
||||
std::string notaryPubkey = "0205a8ad0c1dbc515f149af377981aab58b836af008d4d7ab21bd76faf80550b47";
|
||||
std::string notarySecret = "UxFWWxsf1d7w7K5TvAWSkeX4H95XQKwdwGv49DXwWUTzPTTjHBbU";
|
||||
CKey notaryKey;
|
||||
|
||||
|
||||
/*
|
||||
* We need to have control of clock,
|
||||
* otherwise block production can fail.
|
||||
*/
|
||||
int64_t nMockTime;
|
||||
|
||||
extern uint32_t USE_EXTERNAL_PUBKEY;
|
||||
|
||||
void setupChain()
|
||||
{
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
|
||||
// Settings to get block reward
|
||||
//NOTARY_PUBKEY = _NOTARY_PUBKEY;
|
||||
USE_EXTERNAL_PUBKEY = 1;
|
||||
mapArgs["-mineraddress"] = "bogus";
|
||||
COINBASE_MATURITY = 1;
|
||||
// Global mock time
|
||||
nMockTime = GetTime();
|
||||
|
||||
// Init blockchain
|
||||
ClearDatadirCache();
|
||||
auto pathTemp = GetTempPath() / strprintf("test_komodo_%li_%i", GetTime(), GetRand(100000));
|
||||
boost::filesystem::create_directories(pathTemp);
|
||||
mapArgs["-datadir"] = pathTemp.string();
|
||||
pblocktree = new CBlockTreeDB(1 << 20, true);
|
||||
CCoinsViewDB *pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||
InitBlockIndex();
|
||||
}
|
||||
|
||||
|
||||
void generateBlock(CBlock *block)
|
||||
{
|
||||
UniValue params;
|
||||
params.setArray();
|
||||
params.push_back(1);
|
||||
uint256 blockId;
|
||||
|
||||
SetMockTime(nMockTime++); // CreateNewBlock can fail if not enough time passes
|
||||
|
||||
try {
|
||||
UniValue out = generate(params, false);
|
||||
blockId.SetHex(out[0].getValStr());
|
||||
} catch (const UniValue& e) {
|
||||
FAIL() << "failed to create block: " << e.write().data();
|
||||
}
|
||||
if (block) ASSERT_TRUE(ReadBlockFromDisk(*block, mapBlockIndex[blockId]));
|
||||
}
|
||||
|
||||
|
||||
void acceptTxFail(const CTransaction tx)
|
||||
{
|
||||
CValidationState state;
|
||||
if (!acceptTx(tx, state)) FAIL() << state.GetRejectReason();
|
||||
}
|
||||
|
||||
|
||||
bool acceptTx(const CTransaction tx, CValidationState &state)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return AcceptToMemoryPool(mempool, state, tx, false, NULL);
|
||||
}
|
||||
|
||||
|
||||
static CMutableTransaction spendTx(const CTransaction &txIn, int nOut=0)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
mtx.vin.resize(1);
|
||||
mtx.vin[0].prevout.hash = txIn.GetHash();
|
||||
mtx.vin[0].prevout.n = nOut;
|
||||
mtx.vout.resize(1);
|
||||
mtx.vout[0].nValue = txIn.vout[nOut].nValue - 1000;
|
||||
return mtx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In order to do tests there needs to be inputs to spend.
|
||||
* This method creates a block and returns a transaction that spends the coinbase.
|
||||
*/
|
||||
void getInputTx(CScript scriptPubKey, CTransaction &txIn)
|
||||
{
|
||||
// Get coinbase
|
||||
CBlock block;
|
||||
generateBlock(&block);
|
||||
CTransaction coinbase = block.vtx[0];
|
||||
|
||||
// Create tx
|
||||
auto mtx = spendTx(coinbase);
|
||||
mtx.vout[0].scriptPubKey = scriptPubKey;
|
||||
uint256 hash = SignatureHash(coinbase.vout[0].scriptPubKey, mtx, 0, SIGHASH_ALL, 0, 0);
|
||||
std::vector<unsigned char> vchSig;
|
||||
notaryKey.Sign(hash, vchSig);
|
||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||
mtx.vin[0].scriptSig << vchSig;
|
||||
|
||||
// Accept
|
||||
acceptTxFail(mtx);
|
||||
txIn = CTransaction(mtx);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef TESTUTILS_H
|
||||
#define TESTUTILS_H
|
||||
|
||||
#include "script/cc.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
#define VCH(a,b) std::vector<unsigned char>(a, a + b)
|
||||
@@ -12,4 +12,16 @@ static char ccjsonerr[1000] = "\0";
|
||||
if (!o) FAIL() << "bad json: " << ccjsonerr;
|
||||
|
||||
|
||||
extern std::string notaryPubkey;
|
||||
extern std::string notarySecret;
|
||||
extern CKey notaryKey;
|
||||
|
||||
|
||||
void setupChain();
|
||||
void generateBlock(CBlock *block=NULL);
|
||||
bool acceptTx(const CTransaction tx, CValidationState &state);
|
||||
void acceptTxFail(const CTransaction tx);
|
||||
void getInputTx(CScript scriptPubKey, CTransaction &txIn);
|
||||
|
||||
|
||||
#endif /* TESTUTILS_H */
|
||||
|
||||
Reference in New Issue
Block a user