create functions in main.cpp which can decode and strip NCC commands from a txout.scriptPubKey, and create functions in rpcwallet.cpp which can create transactions with NCC commands. change tests to pass given NCC parameters, add CLAIM_NAME as a script command in script/script.h, and add a few printouts that occur during transaction spends which should be removed later
This commit is contained in:
parent
aec93c1245
commit
d4d3ab8115
12 changed files with 241 additions and 22 deletions
|
@ -17,7 +17,7 @@ static const CAmount COIN = 100000000;
|
||||||
static const CAmount CENT = 1000000;
|
static const CAmount CENT = 1000000;
|
||||||
|
|
||||||
/** No amount larger than this (in satoshi) is valid */
|
/** No amount larger than this (in satoshi) is valid */
|
||||||
static const CAmount MAX_MONEY = 21000000 * COIN;
|
static const CAmount MAX_MONEY = 21000000000 * COIN;
|
||||||
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
||||||
|
|
||||||
/** Type-safe wrapper class to for fee rates
|
/** Type-safe wrapper class to for fee rates
|
||||||
|
|
|
@ -120,12 +120,12 @@ public:
|
||||||
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
|
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
|
||||||
nDefaultPort = 8333;
|
nDefaultPort = 8333;
|
||||||
bnProofOfWorkLimit = ~uint256(0) >> 1;
|
bnProofOfWorkLimit = ~uint256(0) >> 1;
|
||||||
nSubsidyHalvingInterval = 210000;
|
nSubsidyHalvingInterval = 2100000;
|
||||||
nEnforceBlockUpgradeMajority = 750;
|
nEnforceBlockUpgradeMajority = 750;
|
||||||
nRejectBlockOutdatedMajority = 950;
|
nRejectBlockOutdatedMajority = 950;
|
||||||
nToCheckBlockUpgradeMajority = 1000;
|
nToCheckBlockUpgradeMajority = 1000;
|
||||||
nMinerThreads = 2;
|
nMinerThreads = 2;
|
||||||
nTargetTimespan = 30 * 60;//14 * 24 * 60 * 60; // two weeks
|
nTargetTimespan = 30 * 60 * 10;//14 * 24 * 60 * 60; // two weeks
|
||||||
nTargetSpacing = 30;
|
nTargetSpacing = 30;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,10 +170,10 @@ public:
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
hashGenesisBlock = genesis.GetHash();
|
hashGenesisBlock = genesis.GetHash();
|
||||||
printf("%s\n", hashGenesisBlock.GetHex().c_str());
|
//printf("%s\n", hashGenesisBlock.GetHex().c_str());
|
||||||
//assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
|
//assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
|
||||||
assert(hashGenesisBlock == uint256("0x008c55867210a8154af697b7776c6b6cdb26972381eac9f84d18a491374464a3"));
|
assert(hashGenesisBlock == uint256("0x008c55867210a8154af697b7776c6b6cdb26972381eac9f84d18a491374464a3"));
|
||||||
printf("%s\n", genesis.hashMerkleRoot.GetHex().c_str());
|
//printf("%s\n", genesis.hashMerkleRoot.GetHex().c_str());
|
||||||
//assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
|
//assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
|
||||||
assert(genesis.hashMerkleRoot == uint256("0xa7d51d407092059a2beeffab22e65d6176cfb3c33b93515109480aa7c81c9141"));
|
assert(genesis.hashMerkleRoot == uint256("0xa7d51d407092059a2beeffab22e65d6176cfb3c33b93515109480aa7c81c9141"));
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +38,7 @@ bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) {
|
||||||
return false;
|
return false;
|
||||||
if (vout[out.n].IsNull())
|
if (vout[out.n].IsNull())
|
||||||
return false;
|
return false;
|
||||||
|
LogPrintf("In CCoins::Spend for output %d in transaction %s\n", out.n, out.hash.GetHex().c_str());
|
||||||
undo = CTxInUndo(vout[out.n]);
|
undo = CTxInUndo(vout[out.n]);
|
||||||
vout[out.n].SetNull();
|
vout[out.n].SetNull();
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
84
src/main.cpp
84
src/main.cpp
|
@ -616,11 +616,76 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DecodeNCCScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams)
|
||||||
|
{
|
||||||
|
CScript::const_iterator pc = scriptIn.begin();
|
||||||
|
return DecodeNCCScript(scriptIn, op, vvchParams, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DecodeNCCScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams, CScript::const_iterator& pc)
|
||||||
|
{
|
||||||
|
opcodetype opcode;
|
||||||
|
if (!scriptIn.GetOp(pc, opcode))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (opcode != OP_CLAIM_NAME)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
op = opcode;
|
||||||
|
|
||||||
|
std::vector<unsigned char> vchName;
|
||||||
|
std::vector<unsigned char> vchValue;
|
||||||
|
|
||||||
|
// The correct format is:
|
||||||
|
// OP_CLAIM_NAME vchName vchValue OP_DROP2 OP_DROP pubkeyscript
|
||||||
|
// All others are invalid.
|
||||||
|
|
||||||
|
if (!scriptIn.GetOp(pc, opcode, vchName) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!scriptIn.GetOp(pc, opcode, vchValue) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!scriptIn.GetOp(pc, opcode) || opcode != OP_2DROP)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!scriptIn.GetOp(pc, opcode) || opcode != OP_DROP)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vvchParams.push_back(vchName);
|
||||||
|
vvchParams.push_back(vchValue);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript StripNCCScriptPrefix(const CScript& scriptIn)
|
||||||
|
{
|
||||||
|
int op;
|
||||||
|
std::vector<std::vector<unsigned char> > vvchParams;
|
||||||
|
CScript::const_iterator pc = scriptIn.begin();
|
||||||
|
|
||||||
|
if (!DecodeNCCScript(scriptIn, op, vvchParams, pc))
|
||||||
|
{
|
||||||
|
return scriptIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CScript(pc, scriptIn.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool IsStandardTx(const CTransaction& tx, string& reason)
|
bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
// TODO: We may have a different version here
|
||||||
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
|
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
|
||||||
reason = "version";
|
reason = "version";
|
||||||
return false;
|
return false;
|
||||||
|
@ -680,7 +745,10 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
|
||||||
unsigned int nDataOut = 0;
|
unsigned int nDataOut = 0;
|
||||||
txnouttype whichType;
|
txnouttype whichType;
|
||||||
BOOST_FOREACH(const CTxOut& txout, tx.vout) {
|
BOOST_FOREACH(const CTxOut& txout, tx.vout) {
|
||||||
if (!::IsStandard(txout.scriptPubKey, whichType)) {
|
|
||||||
|
const CScript& scriptPubKey = StripNCCScriptPrefix(txout.scriptPubKey);
|
||||||
|
|
||||||
|
if (!::IsStandard(scriptPubKey, whichType)) {
|
||||||
reason = "scriptpubkey";
|
reason = "scriptpubkey";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -744,7 +812,8 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
||||||
vector<vector<unsigned char> > vSolutions;
|
vector<vector<unsigned char> > vSolutions;
|
||||||
txnouttype whichType;
|
txnouttype whichType;
|
||||||
// get the scriptPubKey corresponding to this input:
|
// get the scriptPubKey corresponding to this input:
|
||||||
const CScript& prevScript = prev.scriptPubKey;
|
const CScript& prevScript = StripNCCScriptPrefix(prev.scriptPubKey);
|
||||||
|
|
||||||
if (!Solver(prevScript, whichType, vSolutions))
|
if (!Solver(prevScript, whichType, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
|
int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
|
||||||
|
@ -814,8 +883,9 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||||
{
|
{
|
||||||
const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
|
const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash())
|
const CScript& scriptPubKey = StripNCCScriptPrefix(prevout.scriptPubKey);
|
||||||
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
|
if (scriptPubKey.IsPayToScriptHash())
|
||||||
|
nSigOps += scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
|
||||||
}
|
}
|
||||||
return nSigOps;
|
return nSigOps;
|
||||||
}
|
}
|
||||||
|
@ -1712,6 +1782,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
}
|
}
|
||||||
UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
|
UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
|
||||||
|
|
||||||
|
// TODO: This seems like a good place to actually change the
|
||||||
|
// TODO: tree of NCCs and make the CUndo vector for those changes.
|
||||||
|
|
||||||
vPos.push_back(std::make_pair(tx.GetHash(), pos));
|
vPos.push_back(std::make_pair(tx.GetHash(), pos));
|
||||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -2516,6 +2589,9 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This looks like a good place to check the "merkle" root of the
|
||||||
|
// TODO: NCC tree that will result from applying this block
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,11 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason);
|
||||||
|
|
||||||
bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
|
bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
|
||||||
|
|
||||||
|
bool DecodeNCCScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams);
|
||||||
|
bool DecodeNCCScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& vvchParams, CScript::const_iterator& pc);
|
||||||
|
CScript StripNCCScriptPrefix(const CScript& scriptIn);
|
||||||
|
|
||||||
|
|
||||||
/** Undo information for a CBlock */
|
/** Undo information for a CBlock */
|
||||||
class CBlockUndo
|
class CBlockUndo
|
||||||
{
|
{
|
||||||
|
|
|
@ -310,6 +310,74 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClaimName(const std::vector<unsigned char> vchName, const std::vector<unsigned char> vchValue, CAmount nAmount, CWalletTx& wtxNew)
|
||||||
|
{
|
||||||
|
// Check amount
|
||||||
|
if (nAmount <= 0)
|
||||||
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
|
||||||
|
|
||||||
|
if (nAmount > pwalletMain->GetBalance())
|
||||||
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
|
||||||
|
|
||||||
|
string strError;
|
||||||
|
if (pwalletMain->IsLocked())
|
||||||
|
{
|
||||||
|
strError = "Error: Wallet locked, unable to create transaction!";
|
||||||
|
LogPrintf("SendMoney() : %s", strError);
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get new address
|
||||||
|
CPubKey newKey;
|
||||||
|
if (!pwalletMain->GetKeyFromPool(newKey))
|
||||||
|
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||||
|
|
||||||
|
CScript scriptPubKey = GetScriptForDestination(CTxDestination(newKey.GetID()));
|
||||||
|
CScript claimScript = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP << scriptPubKey;
|
||||||
|
|
||||||
|
CReserveKey reservekey(pwalletMain);
|
||||||
|
CAmount nFeeRequired;
|
||||||
|
if (!pwalletMain->CreateTransaction(claimScript, nAmount, wtxNew, reservekey, nFeeRequired, strError))
|
||||||
|
{
|
||||||
|
if (nAmount + nFeeRequired > pwalletMain->GetBalance())
|
||||||
|
strError = strprintf("Error: This transaction requires a transaction fee of at least %s because if its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
|
||||||
|
LogPrintf("ClaimName() : %s\n", strError);
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
|
}
|
||||||
|
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
|
||||||
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might hapen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Value claimname(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 3)
|
||||||
|
throw runtime_error(
|
||||||
|
"claimname \"name\" \"value\" amount\n"
|
||||||
|
"\nCreate a transaction which issues a claim assigning a value to a name. The claim will be authoritative if the transaction amount is greater than the transaction amount of all other unspent transactions which issue a claim over the same name, and it will remain authoritative as long as it remains unspent. The amount is a real and is rounded to the nearest 0.00000001\n"
|
||||||
|
+ HelpRequiringPassphrase() +
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. \"name\" (string, required) The name to be assigned the value.\n"
|
||||||
|
"2. \"value\" (string, required) The value to assign to the name.\n"
|
||||||
|
"3. \"amount\n (numeric, required) The amount in ncc to send. eg 0.1\n"
|
||||||
|
"\nResult:\n"
|
||||||
|
"\"transactionid\" (string) The transaction id.\n"
|
||||||
|
);
|
||||||
|
string sName = params[0].get_str();
|
||||||
|
string sValue = params[1].get_str();
|
||||||
|
std::vector<unsigned char> vchName (sName.begin(), sName.end());
|
||||||
|
std::vector<unsigned char> vchValue (sValue.begin(), sValue.end());
|
||||||
|
CAmount nAmount = AmountFromValue(params[2]);
|
||||||
|
|
||||||
|
CWalletTx wtx;
|
||||||
|
|
||||||
|
EnsureWalletIsUnlocked();
|
||||||
|
|
||||||
|
ClaimName(vchName, vchValue, nAmount, wtx);
|
||||||
|
|
||||||
|
return wtx.GetHash().GetHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
|
void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
|
||||||
{
|
{
|
||||||
// Check amount
|
// Check amount
|
||||||
|
|
|
@ -29,6 +29,7 @@ enum opcodetype
|
||||||
// push value
|
// push value
|
||||||
OP_0 = 0x00,
|
OP_0 = 0x00,
|
||||||
OP_FALSE = OP_0,
|
OP_FALSE = OP_0,
|
||||||
|
OP_CLAIM_NAME = OP_0,
|
||||||
OP_PUSHDATA1 = 0x4c,
|
OP_PUSHDATA1 = 0x4c,
|
||||||
OP_PUSHDATA2 = 0x4d,
|
OP_PUSHDATA2 = 0x4d,
|
||||||
OP_PUSHDATA4 = 0x4e,
|
OP_PUSHDATA4 = 0x4e,
|
||||||
|
|
|
@ -18,21 +18,21 @@ BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sanity)
|
BOOST_AUTO_TEST_CASE(sanity)
|
||||||
{
|
{
|
||||||
uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
// uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
|
||||||
uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
// uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
|
// BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
|
// BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
|
||||||
|
|
||||||
|
|
||||||
// Wrong hashes at checkpoints should fail:
|
// Wrong hashes at checkpoints should fail:
|
||||||
BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444));
|
// BOOST_CHECK(!Checkpoints::CheckBlock(11111, p134444));
|
||||||
BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111));
|
// BOOST_CHECK(!Checkpoints::CheckBlock(134444, p11111));
|
||||||
|
|
||||||
// ... but any hash not at a checkpoint should succeed:
|
// ... but any hash not at a checkpoint should succeed:
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444));
|
// BOOST_CHECK(Checkpoints::CheckBlock(11111+1, p134444));
|
||||||
BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111));
|
// BOOST_CHECK(Checkpoints::CheckBlock(134444+1, p11111));
|
||||||
|
|
||||||
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444);
|
// BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate() >= 134444);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -18,7 +18,8 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test)
|
||||||
nSum += nSubsidy * 1000;
|
nSum += nSubsidy * 1000;
|
||||||
BOOST_CHECK(MoneyRange(nSum));
|
BOOST_CHECK(MoneyRange(nSum));
|
||||||
}
|
}
|
||||||
BOOST_CHECK(nSum == 2099999997690000ULL);
|
//BOOST_CHECK(nSum == 2099999997690000ULL);
|
||||||
|
BOOST_CHECK(nSum == 20781250000000000LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(miner_tests)
|
BOOST_AUTO_TEST_SUITE(miner_tests)
|
||||||
|
|
||||||
static
|
/*static
|
||||||
struct {
|
struct {
|
||||||
unsigned char extranonce;
|
unsigned char extranonce;
|
||||||
unsigned int nonce;
|
unsigned int nonce;
|
||||||
|
@ -45,6 +45,41 @@ struct {
|
||||||
{1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
|
{1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
|
||||||
{2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
|
{2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
|
||||||
{2, 0xbbbeb305}, {2, 0xfe1c810a},
|
{2, 0xbbbeb305}, {2, 0xfe1c810a},
|
||||||
|
};*/
|
||||||
|
|
||||||
|
static
|
||||||
|
struct {
|
||||||
|
unsigned char extranonce;
|
||||||
|
unsigned int nonce;
|
||||||
|
} blockinfo[] = {
|
||||||
|
{4, 0x00000002}, {2, 0x00000002}, {1, 0x00000000}, {1, 0x00000001}, //0
|
||||||
|
{2, 0x00000001}, {2, 0x00000002}, {1, 0x00000000}, {2, 0x0000000b}, //4
|
||||||
|
{2, 0x00000000}, {1, 0x00000000}, {1, 0x00000000}, {2, 0x00000001}, //8
|
||||||
|
{2, 0x00000000}, {1, 0x00000000}, {2, 0x00000000}, {2, 0x00000001}, //12
|
||||||
|
{1, 0x00000000}, {2, 0x00000004}, {1, 0x00000000}, {1, 0x00000000}, //16
|
||||||
|
{3, 0x00000002}, {2, 0x00000000}, {2, 0x00000000}, {1, 0x00000000}, //20
|
||||||
|
{2, 0x00000000}, {1, 0x00000002}, {2, 0x00000000}, {2, 0x00000000}, //24
|
||||||
|
{2, 0x00000000}, {2, 0x00000001}, {2, 0x00000000}, {2, 0x00000000}, //28
|
||||||
|
{1, 0x00000000}, {2, 0x00000001}, {2, 0x00000000}, {1, 0x00000000}, //32
|
||||||
|
{2, 0x00000001}, {1, 0x00000000}, {2, 0x00000001}, {1, 0x00000000}, //36
|
||||||
|
{1, 0x00000001}, {3, 0x00000000}, {2, 0x00000000}, {5, 0x00000002}, //40
|
||||||
|
{1, 0x00000001}, {5, 0x00000000}, {1, 0x00000005}, {1, 0x00000000}, //44
|
||||||
|
{1, 0x00000000}, {2, 0x00000002}, {1, 0x00000002}, {1, 0x00000000}, //48
|
||||||
|
{1, 0x00000000}, {1, 0x00000000}, {5, 0x00000001}, {5, 0x00000000}, //52
|
||||||
|
{1, 0x00000000}, {1, 0x00000000}, {6, 0x00000000}, {2, 0x00000001}, //56
|
||||||
|
{2, 0x00000000}, {1, 0x00000000}, {1, 0x00000001}, {1, 0x00000002}, //60
|
||||||
|
{2, 0x00000001}, {2, 0x00000000}, {1, 0x00000003}, {1, 0x00000001}, //64
|
||||||
|
{1, 0x00000000}, {5, 0x00000000}, {5, 0x00000002}, {1, 0x00000001}, //68
|
||||||
|
{1, 0x00000001}, {2, 0x00000000}, {2, 0x00000001}, {1, 0x00000003}, //72
|
||||||
|
{2, 0x00000002}, {1, 0x00000000}, {2, 0x00000000}, {2, 0x00000006}, //76
|
||||||
|
{1, 0x00000000}, {1, 0x00000000}, {1, 0x00000001}, {5, 0x00000000}, //80
|
||||||
|
{1, 0x00000001}, {1, 0x00000001}, {1, 0x00000000}, {1, 0x00000002}, //84
|
||||||
|
{1, 0x00000000}, {1, 0x00000000}, {1, 0x00000002}, {2, 0x00000001}, //88
|
||||||
|
{0, 0x00000003}, {1, 0x00000004}, {2, 0x00000000}, {2, 0x00000001}, //92
|
||||||
|
{2, 0x00000000}, {1, 0x00000002}, {1, 0x00000000}, {1, 0x00000002}, //96
|
||||||
|
{1, 0x00000000}, {1, 0x00000003}, {1, 0x00000000}, {5, 0x00000000}, //100
|
||||||
|
{2, 0x00000000}, {1, 0x00000000}, {1, 0x00000001}, {1, 0x00000001}, //104
|
||||||
|
{2, 0x00000000}, {2, 0x00000002}, //108
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
|
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
|
||||||
|
@ -80,6 +115,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
txFirst.push_back(new CTransaction(pblock->vtx[0]));
|
txFirst.push_back(new CTransaction(pblock->vtx[0]));
|
||||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
||||||
pblock->nNonce = blockinfo[i].nonce;
|
pblock->nNonce = blockinfo[i].nonce;
|
||||||
|
/*bool fFound = false;
|
||||||
|
for (int j = 0; !fFound; j++)
|
||||||
|
{
|
||||||
|
pblock->nNonce = j;
|
||||||
|
if (CheckProofOfWork(pblock->GetHash(), pblock->nBits))
|
||||||
|
{
|
||||||
|
fFound = true;
|
||||||
|
std::cout << "Block number: " << i << std::endl;
|
||||||
|
std::cout << "Nonce: " << std::hex << pblock->nNonce << std::dec << std::endl;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock));
|
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock));
|
||||||
BOOST_CHECK(state.IsValid());
|
BOOST_CHECK(state.IsValid());
|
||||||
|
@ -198,6 +244,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
delete pblocktemplate;
|
delete pblocktemplate;
|
||||||
mempool.clear();
|
mempool.clear();
|
||||||
|
|
||||||
|
/* This has been removed because we don't have that many blocks in the active chain yet.
|
||||||
|
It should be returned when we do.
|
||||||
// subsidy changing
|
// subsidy changing
|
||||||
int nHeight = chainActive.Height();
|
int nHeight = chainActive.Height();
|
||||||
chainActive.Tip()->nHeight = 209999;
|
chainActive.Tip()->nHeight = 209999;
|
||||||
|
@ -207,6 +255,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
|
||||||
delete pblocktemplate;
|
delete pblocktemplate;
|
||||||
chainActive.Tip()->nHeight = nHeight;
|
chainActive.Tip()->nHeight = nHeight;
|
||||||
|
*/
|
||||||
|
|
||||||
// non-final txs in mempool
|
// non-final txs in mempool
|
||||||
SetMockTime(chainActive.Tip()->GetMedianTimePast()+1);
|
SetMockTime(chainActive.Tip()->GetMedianTimePast()+1);
|
||||||
|
|
|
@ -373,6 +373,18 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
||||||
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
||||||
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
|
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
|
||||||
BOOST_CHECK(!IsStandardTx(t, reason));
|
BOOST_CHECK(!IsStandardTx(t, reason));
|
||||||
|
|
||||||
|
// NCC transactions
|
||||||
|
|
||||||
|
t.vout.resize(1);
|
||||||
|
string sName = "testname";
|
||||||
|
string sValue = "testvalue";
|
||||||
|
std::vector<unsigned char> vchName (sName.begin(), sName.end());
|
||||||
|
std::vector<unsigned char> vchValue (sValue.begin(), sValue.end());
|
||||||
|
CScript scriptPubKey = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
||||||
|
t.vout[0].scriptPubKey = scriptPubKey + GetScriptForDestination(key.GetPubKey().GetID());
|
||||||
|
t.vout[0].nValue = 10*COIN;
|
||||||
|
BOOST_CHECK(IsStandardTx(t, reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -15,11 +15,15 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
|
void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
|
||||||
if (coins.IsPruned())
|
if (coins.IsPruned()) {
|
||||||
|
LogPrintf("BatchWriteCoins erasing %s\n", hash.GetHex().c_str());
|
||||||
batch.Erase(make_pair('c', hash));
|
batch.Erase(make_pair('c', hash));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
LogPrintf("BatchWriteCoins writing %s\n", hash.GetHex().c_str());
|
||||||
batch.Write(make_pair('c', hash), coins);
|
batch.Write(make_pair('c', hash), coins);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
|
void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
|
||||||
batch.Write('B', hash);
|
batch.Write('B', hash);
|
||||||
|
|
Loading…
Reference in a new issue