Implement a hard fork for extended/infinite claim expiration times #112
12 changed files with 143 additions and 10 deletions
|
@ -182,6 +182,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
rpcblockchain.cpp \
|
||||
rpcmining.cpp \
|
||||
rpcmisc.cpp \
|
||||
rpcncctrie.cpp \
|
||||
rpcnet.cpp \
|
||||
rpcrawtransaction.cpp \
|
||||
rpcserver.cpp \
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
//! block header
|
||||
int nVersion;
|
||||
uint256 hashMerkleRoot;
|
||||
uint256 hashNCCTrie;
|
||||
unsigned int nTime;
|
||||
unsigned int nBits;
|
||||
unsigned int nNonce;
|
||||
|
@ -159,6 +160,7 @@ public:
|
|||
|
||||
nVersion = 0;
|
||||
hashMerkleRoot = uint256();
|
||||
hashNCCTrie = uint256();
|
||||
nTime = 0;
|
||||
nBits = 0;
|
||||
nNonce = 0;
|
||||
|
@ -175,6 +177,7 @@ public:
|
|||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
hashNCCTrie = block.hashNCCTrie;
|
||||
nTime = block.nTime;
|
||||
nBits = block.nBits;
|
||||
nNonce = block.nNonce;
|
||||
|
@ -205,6 +208,7 @@ public:
|
|||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashNCCTrie = hashNCCTrie;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
|
@ -239,9 +243,10 @@ public:
|
|||
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, ncctrie=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
hashMerkleRoot.ToString(),
|
||||
hashNCCTrie.ToString(),
|
||||
GetBlockHash().ToString());
|
||||
}
|
||||
|
||||
|
@ -311,6 +316,7 @@ public:
|
|||
READWRITE(this->nVersion);
|
||||
READWRITE(hashPrev);
|
||||
READWRITE(hashMerkleRoot);
|
||||
READWRITE(hashNCCTrie);
|
||||
READWRITE(nTime);
|
||||
READWRITE(nBits);
|
||||
READWRITE(nNonce);
|
||||
|
@ -322,6 +328,7 @@ public:
|
|||
block.nVersion = nVersion;
|
||||
block.hashPrevBlock = hashPrev;
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashNCCTrie = hashNCCTrie;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
|
|
|
@ -412,12 +412,12 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
|||
//
|
||||
bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash)
|
||||
{
|
||||
// Write the first 76 bytes of the block header to a double-SHA256 state.
|
||||
// Write the first 108 bytes of the block header to a double-SHA256 state.
|
||||
CHash256 hasher;
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << *pblock;
|
||||
assert(ss.size() == 80);
|
||||
hasher.Write((unsigned char*)&ss[0], 76);
|
||||
assert(ss.size() == 112);
|
||||
hasher.Write((unsigned char*)&ss[0], 108);
|
||||
|
||||
while (true) {
|
||||
nNonce++;
|
||||
|
|
|
@ -59,7 +59,7 @@ bool CNCCTrieNode::removeValue(CNodeValue val, bool * pfChanged)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CNCCTrieNode::getValue(CNodeValue& value)
|
||||
bool CNCCTrieNode::getValue(CNodeValue& value) const
|
||||
{
|
||||
if (values.empty())
|
||||
return false;
|
||||
|
@ -80,6 +80,62 @@ bool CNCCTrie::empty() const
|
|||
return root.empty();
|
||||
}
|
||||
|
||||
bool CNCCTrie::recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const
|
||||
{
|
||||
using namespace json_spirit;
|
||||
Object objNode;
|
||||
objNode.push_back(Pair("name", name));
|
||||
objNode.push_back(Pair("hash", current->hash.GetHex()));
|
||||
CNodeValue val;
|
||||
if (current->getValue(val))
|
||||
{
|
||||
objNode.push_back(Pair("txid", val.txhash.GetHex()));
|
||||
objNode.push_back(Pair("n", (int)val.nOut));
|
||||
objNode.push_back(Pair("value", val.nAmount));
|
||||
objNode.push_back(Pair("height", val.nHeight));
|
||||
}
|
||||
ret.push_back(objNode);
|
||||
for (nodeMapType::const_iterator it = current->children.begin(); it != current->children.end(); ++it)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << name << it->first;
|
||||
if (!recursiveDumpToJSON(ss.str(), it->second, ret))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
json_spirit::Array CNCCTrie::dumpToJSON() const
|
||||
{
|
||||
json_spirit::Array ret;
|
||||
if (!recursiveDumpToJSON("", &root, ret))
|
||||
LogPrintf("Something went wrong dumping to JSON");
|
||||
return ret;
|
||||
}
|
||||
|
||||
json_spirit::Object CNCCTrie::getInfoForName(const std::string& name) const
|
||||
{
|
||||
using namespace json_spirit;
|
||||
Object ret;
|
||||
const CNCCTrieNode* current = &root;
|
||||
for (std::string::const_iterator itname = name.begin(); itname != name.end(); ++itname)
|
||||
{
|
||||
nodeMapType::const_iterator itchildren = current->children.find(*itname);
|
||||
if (itchildren == current->children.end())
|
||||
return ret;
|
||||
current = itchildren->second;
|
||||
}
|
||||
CNodeValue val;
|
||||
if (current->getValue(val))
|
||||
{
|
||||
ret.push_back(Pair("txid", val.txhash.GetHex()));
|
||||
ret.push_back(Pair("n", (int)val.nOut));
|
||||
ret.push_back(Pair("value", val.nAmount));
|
||||
ret.push_back(Pair("height", val.nHeight));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CNCCTrie::checkConsistency()
|
||||
{
|
||||
if (empty())
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
|
||||
class CNodeValue
|
||||
{
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
std::vector<CNodeValue> values;
|
||||
bool insertValue(CNodeValue val, bool * fChanged = NULL);
|
||||
bool removeValue(CNodeValue val, bool * fChanged = NULL);
|
||||
bool getValue(CNodeValue& val);
|
||||
bool getValue(CNodeValue& val) const;
|
||||
bool empty() const {return children.empty() && values.empty();}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
@ -129,6 +129,8 @@ public:
|
|||
bool empty() const;
|
||||
bool checkConsistency();
|
||||
bool ReadFromDisk(bool check = false);
|
||||
json_spirit::Array dumpToJSON() const;
|
||||
json_spirit::Object getInfoForName(const std::string& name) const;
|
||||
friend class CNCCTrieCache;
|
||||
private:
|
||||
bool update(nodeCacheType& cache, hashMapType& hashes);
|
||||
|
@ -138,6 +140,7 @@ private:
|
|||
bool recursiveCheckConsistency(CNCCTrieNode* node);
|
||||
bool BatchWrite(nodeCacheType& changedNodes, std::vector<std::string>& deletedNames);
|
||||
bool InsertFromDisk(const std::string& name, CNCCTrieNode* node);
|
||||
bool recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const;
|
||||
CNCCTrieNode root;
|
||||
};
|
||||
|
||||
|
|
|
@ -111,11 +111,12 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
|
|||
std::string CBlock::ToString() const
|
||||
{
|
||||
std::stringstream s;
|
||||
s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
|
||||
s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, hashNCCTrie=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
|
||||
GetHash().ToString(),
|
||||
nVersion,
|
||||
hashPrevBlock.ToString(),
|
||||
hashMerkleRoot.ToString(),
|
||||
hashNCCTrie.ToString(),
|
||||
nTime, nBits, nNonce,
|
||||
vtx.size());
|
||||
for (unsigned int i = 0; i < vtx.size(); i++)
|
||||
|
|
|
@ -46,10 +46,10 @@ public:
|
|||
nVersion = this->nVersion;
|
||||
READWRITE(hashPrevBlock);
|
||||
READWRITE(hashMerkleRoot);
|
||||
READWRITE(hashNCCTrie);
|
||||
READWRITE(nTime);
|
||||
READWRITE(nBits);
|
||||
READWRITE(nNonce);
|
||||
READWRITE(hashNCCTrie);
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
|
@ -118,10 +118,10 @@ public:
|
|||
block.nVersion = nVersion;
|
||||
block.hashPrevBlock = hashPrevBlock;
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashNCCTrie = hashNCCTrie;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
block.hashNCCTrie = hashNCCTrie;
|
||||
return block;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
|
|||
result.push_back(Pair("height", blockindex->nHeight));
|
||||
result.push_back(Pair("version", block.nVersion));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("nccroot", block.hashNCCTrie.GetHex()));
|
||||
Array txs;
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
|
@ -266,6 +267,7 @@ Value getblock(const Array& params, bool fHelp)
|
|||
" \"height\" : n, (numeric) The block height or index\n"
|
||||
" \"version\" : n, (numeric) The block version\n"
|
||||
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
|
||||
" \"nccroot\" : \"xxxx\", (string) The hash of the root of the NCC trie\n"
|
||||
" \"tx\" : [ (array of string) The transaction ids\n"
|
||||
" \"transactionid\" (string) The transaction id\n"
|
||||
" ,...\n"
|
||||
|
|
55
src/rpcncctrie.cpp
Normal file
55
src/rpcncctrie.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "main.h"
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
//using namespace std;
|
||||
|
||||
|
||||
Value getncctrie(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 0)
|
||||
throw std::runtime_error(
|
||||
"getncctrie\n"
|
||||
"Return the entire NCC trie.\n"
|
||||
"Arguments:\n"
|
||||
"None\n"
|
||||
"Result: \n"
|
||||
"{\n"
|
||||
" \"name\" (string) the name of the node\n"
|
||||
" \"hash\" (string) the hash of the node\n"
|
||||
" \"txid\" (string) (if value exists) the hash of the transaction which has successfully claimed this name\n"
|
||||
" \"n\" (numeric) (if value exists) vout value\n"
|
||||
" \"value\" (numeric) (if value exists) txout value\n"
|
||||
" \"height\" (numeric) (if value exists) the height of the block in which this transaction is located\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
Array ret = pnccTrie->dumpToJSON();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Value gettxinfoforname(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
"gettxinfoforname\n"
|
||||
"Return information about the transaction that has successfully claimed a name, if one exists\n"
|
||||
"Arguments:\n"
|
||||
"1. \"name\" (string) the name about which to return info\n"
|
||||
"Result: \n"
|
||||
"\"txid\" (string) the hash of the transaction which successfully claimed the name\n"
|
||||
"\"n\" (numeric) vout value\n"
|
||||
"\"value\" (numeric) txout value\n"
|
||||
"\"height\" (numeric) the height of the block in which this transaction is located\n"
|
||||
);
|
||||
LOCK(cs_main);
|
||||
|
||||
std::string name = params[0].get_str();
|
||||
|
||||
Object ret = pnccTrie->getInfoForName(name);
|
||||
return ret;
|
||||
}
|
|
@ -380,6 +380,10 @@ static const CRPCCommand vRPCCommands[] =
|
|||
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true },
|
||||
{ "wallet", "walletpassphrase", &walletpassphrase, true, true },
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
/* NCC trie */
|
||||
{ "ncctrie", "getncctrie", &getncctrie, true, false},
|
||||
{ "ncctrie", "gettxinfoforname", &gettxinfoforname, true, false},
|
||||
};
|
||||
|
||||
CRPCTable::CRPCTable()
|
||||
|
|
|
@ -237,6 +237,9 @@ extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fH
|
|||
extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getncctrie(const json_spirit::Array& params, bool fHelp); // in rpcncctrie.cpp
|
||||
extern json_spirit::Value gettxinfoforname(const json_spirit::Array& params, bool fHelp);
|
||||
|
||||
// in rest.cpp
|
||||
extern bool HTTPReq_REST(AcceptedConnection *conn,
|
||||
const std::string& strURI,
|
||||
|
|
|
@ -216,6 +216,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
|||
pindexNew->nUndoPos = diskindex.nUndoPos;
|
||||
pindexNew->nVersion = diskindex.nVersion;
|
||||
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
|
||||
pindexNew->hashNCCTrie = diskindex.hashNCCTrie;
|
||||
pindexNew->nTime = diskindex.nTime;
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
|
|
Loading…
Reference in a new issue