Commit 1814d110 authored by Mark Brooker's avatar Mark Brooker

Merge branch 'Current-dev' of https://gitlab.crownplatform.com/crown/crown-core into Current-dev

parents 0404ea9a 3ca7d374
variables:
RELEASE_VERSION: "0.13.9.3"
RELEASE_VERSION: "0.13.9.5"
GIT_STRATEGY: "clone"
MAKEJOBS: "-j4"
CCACHE_SIZE: "100M"
......
......@@ -3,7 +3,7 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 13)
define(_CLIENT_VERSION_REVISION, 9)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_BUILD, 5)
define(_COPYRIGHT_YEAR, 2019)
AC_INIT([Crown Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[[email protected]],[crown])
AC_CONFIG_SRCDIR([src/main.cpp])
......
......@@ -17,7 +17,7 @@
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 13
#define CLIENT_VERSION_REVISION 9
#define CLIENT_VERSION_BUILD 3
#define CLIENT_VERSION_BUILD 5
/**
* Copyright year (2009-this)
......
......@@ -958,6 +958,10 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
// check version 3 transaction types
if (tx.nVersion >= 3)
{
if (!IsSporkActive(SPORK_17_NFT_TX))
{
return state.DoS(100, false, REJECT_INVALID, "nft-tx-spork-off");
}
if (tx.nType != TRANSACTION_NORMAL &&
tx.nType != TRANSACTION_GOVERNANCE_VOTE &&
tx.nType != TRANSACTION_NF_TOKEN_REGISTER &&
......@@ -970,7 +974,9 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
}
// all version 1 transactions are normal
else if (tx.nType != TRANSACTION_NORMAL)
{
return state.DoS(100, false, REJECT_INVALID, "bad-txns-type");
}
// Basic checks that don't depend on any context
if (tx.vin.empty())
......
......@@ -36,7 +36,8 @@ namespace Platform
if (nftProto.nftRegSign < static_cast<uint8_t>(NftRegSignMin) || nftProto.nftRegSign > static_cast<uint8_t>(NftRegSignMax))
return state.DoS(10, false, REJECT_INVALID, "bad-nft-proto-reg-tx-reg-sign");
if (nftProto.tokenProtocolName.size() > NfTokenProtocol::TOKEN_PROTOCOL_NAME_MAX)
if (nftProto.tokenProtocolName.size() < NfTokenProtocol::TOKEN_PROTOCOL_NAME_MIN
|| nftProto.tokenProtocolName.size() > NfTokenProtocol::TOKEN_PROTOCOL_NAME_MAX)
return state.DoS(10, false, REJECT_INVALID, "bad-nft-proto-reg-tx-proto-name");
if (nftProto.tokenMetadataMimeType.size() > NfTokenProtocol::TOKEN_METADATA_MIMETYPE_MAX)
......
......@@ -27,6 +27,7 @@ namespace Platform
public:
/// NF token protocol unique symbol/identifier, can be an a abbreviated name describing this NF token type
/// Represented as a base32 string, can only contain characters: .abcdefghijklmnopqrstuvwxyz12345
/// Dots(.) are not allowed as a first and last characters
/// Minimum length 3 symbols, maximum length 12 symbols
uint64_t tokenProtocolId;
......@@ -57,7 +58,9 @@ namespace Platform
CKeyID tokenProtocolOwnerId;
//TODO: add admin key to the protocol structure. add option to use setup admin key rights including tranfering ownership
static const unsigned TOKEN_PROTOCOL_ID_MIN = 3;
static const unsigned TOKEN_PROTOCOL_ID_MAX = 12;
static const unsigned TOKEN_PROTOCOL_NAME_MIN = 3;
static const unsigned TOKEN_PROTOCOL_NAME_MAX = 24;
static const unsigned TOKEN_METADATA_SCHEMA_URI_MAX = 128;
static const unsigned TOKEN_METADATA_MIMETYPE_MAX = 32;
......
......@@ -19,6 +19,8 @@ namespace Platform
NfTokenRegTxBuilder & SetTokenProtocol(const json_spirit::Value & tokenProtocolId)
{
m_nfToken.tokenProtocolId = StringToProtocolName(tokenProtocolId.get_str().c_str());
if (m_nfToken.tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
return *this;
}
......
......@@ -325,19 +325,19 @@ namespace Platform
}
void NfTokensManager::ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
int height,
int count,
int skipFromTip) const
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const
{
LOCK(m_cs);
if (PlatformDb::Instance().OptimizeSpeed())
{
auto originalRange = m_nfTokensIndexSet.get<Tags::Height>().range(
bmx::unbounded,
[&](int curHeight) { return curHeight <= height; }
[&](unsigned int curHeight) { return curHeight <= height; }
);
long rangeSize = std::distance(originalRange.first, originalRange.second);
unsigned long rangeSize = std::distance(originalRange.first, originalRange.second);
assert(rangeSize >= 0);
auto begin = skipFromTip + count > rangeSize ? originalRange.first : std::prev(originalRange.second, skipFromTip + count);
......@@ -359,9 +359,9 @@ namespace Platform
void NfTokensManager::ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
uint64_t nftProtoId,
int height,
int count,
int skipFromTip) const
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const
{
LOCK(m_cs);
if (PlatformDb::Instance().OptimizeSpeed())
......@@ -369,7 +369,7 @@ namespace Platform
auto first = m_nfTokensIndexSet.get<Tags::ProtocolIdHeight>().lower_bound(std::make_tuple(nftProtoId, 0));
auto second = m_nfTokensIndexSet.get<Tags::ProtocolIdHeight>().upper_bound(std::make_tuple(nftProtoId, height));
long rangeSize = std::distance(first, second);
unsigned long rangeSize = std::distance(first, second);
assert(rangeSize >= 0);
auto begin = skipFromTip + count > rangeSize ? first : std::prev(second, skipFromTip + count);
......@@ -391,9 +391,9 @@ namespace Platform
void NfTokensManager::ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
CKeyID keyId,
int height,
int count,
int skipFromTip) const
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const
{
LOCK(m_cs);
if (PlatformDb::Instance().OptimizeSpeed())
......@@ -401,7 +401,7 @@ namespace Platform
auto first = m_nfTokensIndexSet.get<Tags::OwnerId>().lower_bound(std::make_tuple(keyId, 0));
auto second = m_nfTokensIndexSet.get<Tags::OwnerId>().upper_bound(std::make_tuple(keyId, height));
long rangeSize = std::distance(first, second);
unsigned long rangeSize = std::distance(first, second);
assert(rangeSize >= 0);
auto begin = skipFromTip + count > rangeSize ? first : std::prev(second, skipFromTip + count);
......@@ -424,9 +424,9 @@ namespace Platform
void NfTokensManager::ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
uint64_t nftProtoId,
CKeyID keyId,
int height,
int count,
int skipFromTip) const
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const
{
LOCK(m_cs);
if (PlatformDb::Instance().OptimizeSpeed())
......@@ -434,7 +434,7 @@ namespace Platform
auto first = m_nfTokensIndexSet.get<Tags::ProtocolIdOwnerId>().lower_bound(std::make_tuple(nftProtoId, keyId, 0));
auto second = m_nfTokensIndexSet.get<Tags::ProtocolIdOwnerId>().upper_bound(std::make_tuple(nftProtoId, keyId, height));
long rangeSize = std::distance(first, second);
unsigned long rangeSize = std::distance(first, second);
assert(rangeSize >= 0);
auto begin = skipFromTip + count > rangeSize ? first : std::prev(second, skipFromTip + count);
......
......@@ -215,28 +215,28 @@ namespace Platform
void ProcessFullNftIndexRange(std::function<bool(const NfTokenIndex &)> nftIndexHandler) const;
void ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
int height,
int count,
int skipFromTip) const;
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const;
void ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
uint64_t nftProtoId,
int height,
int count,
int skipFromTip) const;
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const;
void ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
CKeyID keyId,
int height,
int count,
int skipFromTip) const;
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const;
void ProcessNftIndexRangeByHeight(std::function<bool(const NfTokenIndex &)> nftIndexHandler,
uint64_t nftProtoId,
CKeyID keyId,
int height,
int count,
int skipFromTip) const;
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const;
/// Delete a specified nf-token
bool Delete(uint64_t protocolId, const uint256 & tokenId);
......
......@@ -11,6 +11,7 @@
#include "platform/platform-utils.h"
#include "platform/rpc/specialtx-rpc-utils.h"
#include "nf-token-protocol-reg-tx.h"
#include "nf-token.h"
namespace Platform
{
......@@ -20,17 +21,20 @@ namespace Platform
NftProtocolRegTxBuilder & SetTokenProtocol(const json_spirit::Value & tokenProtocolId)
{
auto nftProtoStr = tokenProtocolId.get_str();
if (nftProtoStr.size() > NfTokenProtocol::TOKEN_PROTOCOL_ID_MAX)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID is longer than permitted");
if (nftProtoStr.size() < NfTokenProtocol::TOKEN_PROTOCOL_ID_MIN || nftProtoStr.size() > NfTokenProtocol::TOKEN_PROTOCOL_ID_MAX)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID must be between 3 and 12 symbols long");
m_nftProto.tokenProtocolId = StringToProtocolName(nftProtoStr.c_str());
if (m_nftProto.tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
return *this;
}
NftProtocolRegTxBuilder & SetTokenProtocolName(const json_spirit::Value & tokenProtocolName)
{
m_nftProto.tokenProtocolName = tokenProtocolName.get_str();
if (m_nftProto.tokenProtocolName.size() > NfTokenProtocol::TOKEN_PROTOCOL_NAME_MAX)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT Protocol name is longer than permitted");
if (m_nftProto.tokenProtocolName.size() < NfTokenProtocol::TOKEN_PROTOCOL_NAME_MIN
|| m_nftProto.tokenProtocolName.size() > NfTokenProtocol::TOKEN_PROTOCOL_NAME_MAX)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT Protocol name must be between 3 and 24 symbols long");
return *this;
}
......@@ -81,7 +85,7 @@ namespace Platform
NftProtocolRegTxBuilder & SetMaxMetadataSize(const json_spirit::Value & value)
{
m_nftProto.maxMetadataSize = ParseInt32V(value, "maxMetadataSize");
m_nftProto.maxMetadataSize = ParseUInt8V(value, "maxMetadataSize");
return *this;
}
......
......@@ -123,17 +123,17 @@ namespace Platform
}
void NftProtocolsManager::ProcessNftProtoIndexRangeByHeight(std::function<bool(const NftProtoIndex &)> protoIndexHandler,
int height,
int count,
int skipFromTip) const
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const
{
LOCK(m_cs);
auto originalRange = m_nftProtoIndexSet.get<Tags::Height>().range(
bmx::unbounded,
[&](int curHeight) { return curHeight <= height; }
[&](unsigned int curHeight) { return curHeight <= height; }
);
long rangeSize = std::distance(originalRange.first, originalRange.second);
unsigned long rangeSize = std::distance(originalRange.first, originalRange.second);
assert(rangeSize >= 0);
auto begin = skipFromTip + count > rangeSize ? originalRange.first : std::prev(originalRange.second, skipFromTip + count);
......
......@@ -106,9 +106,9 @@ namespace Platform
void ProcessFullNftProtoIndexRange(std::function<bool(const NftProtoIndex &)> protoIndexHandler) const;
void ProcessNftProtoIndexRangeByHeight(std::function<bool(const NftProtoIndex &)> protoIndexHandler,
int height,
int count,
int skipFromTip) const;
unsigned int height,
unsigned int count,
unsigned int skipFromTip) const;
/// Delete a specified nf-token protocol
bool Delete(uint64_t protocolId);
......
......@@ -11,6 +11,11 @@
namespace Platform
{
static bool IsValidSymbol(char c)
{
return (( c >= 'a' && c <= 'z' ) || ( c >= '1' && c <= '5' ) || c == '.');
}
/**
* Converts a base32 symbol into its binary representation, used by StringToProtocolName()
*
......@@ -40,13 +45,20 @@ namespace Platform
uint32_t len = 0;
while( str[len] ) ++len;
if (str[0] == '.' || (len > 1 && str[len - 1] == '.'))
return static_cast<uint64_t >(-1);
uint64_t value = 0;
for( uint32_t i = 0; i <= 12; ++i )
{
uint64_t c = 0;
if( i < len && i <= 12 )
c = uint64_t(CharToSymbol( str[i] ));
{
if (!IsValidSymbol(str[i]))
return static_cast<uint64_t >(-1);
c = uint64_t(CharToSymbol(str[i]));
}
if( i < 12 )
{
......
......@@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <spork.h>
#include <platform/nf-token/nf-token-protocol.h>
#include "primitives/transaction.h"
#include "platform/specialtx.h"
......@@ -14,6 +15,11 @@
json_spirit::Value nftoken(const json_spirit::Array& params, bool fHelp)
{
if (!IsSporkActive(SPORK_17_NFT_TX))
{
throw std::runtime_error("NFT spork is off");
}
std::string command = Platform::GetCommand(params, "usage: nftoken register(issue)|list|get|getbytxid|totalsupply|balanceof|ownerof");
if (command == "register" || command == "issue")
......@@ -199,8 +205,11 @@ List the most recent 20 NFT records
if (params.size() > 1)
{
std::string nftProtoIdStr = params[1].get_str();
if (nftProtoIdStr != "*")
if (nftProtoIdStr != "*") {
nftProtoId = StringToProtocolName(nftProtoIdStr.c_str());
if (nftProtoId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
}
}
CKeyID filterKeyId;
......@@ -209,12 +218,12 @@ List the most recent 20 NFT records
filterKeyId = ParsePubKeyIDFromAddress(params[2].get_str(), "nfTokenOwnerAddr");
}
static const int defaultTxsCount = 20;
static const int defaultSkipFromTip = 0;
int count = (params.size() > 3) ? ParseInt32V(params[3], "count") : defaultTxsCount;
int skipFromTip = (params.size() > 4) ? ParseInt32V(params[4], "skipFromTip") : defaultSkipFromTip;
static unsigned const int defaultTxsCount = 20;
static unsigned const int defaultSkipFromTip = 0;
unsigned int count = (params.size() > 3) ? ParseUInt32V(params[3], "count") : defaultTxsCount;
unsigned int skipFromTip = (params.size() > 4) ? ParseUInt32V(params[4], "skipFromTip") : defaultSkipFromTip;
int height = (params.size() > 5 && params[5].get_str() != "*") ? ParseInt32V(params[5], "height") : chainActive.Height();
unsigned int height = (params.size() > 5 && params[5].get_str() != "*") ? ParseUInt32V(params[5], "height") : chainActive.Height();
if (height < 0 || height > chainActive.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height is out of range");
......@@ -275,6 +284,8 @@ Examples:
GetNfTokenHelp();
uint64_t tokenProtocolId = StringToProtocolName(params[1].get_str().c_str());
if (tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
uint256 tokenId = ParseHashV(params[2].get_str(), "nfTokenId");
auto nftIndex = NfTokensManager::Instance().GetNfTokenIndex(tokenProtocolId, tokenId);
......@@ -340,6 +351,8 @@ Examples:
if (params.size() == 2)
{
uint64_t tokenProtocolId = StringToProtocolName(params[1].get_str().c_str());
if (tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
totalSupply = NfTokensManager::Instance().TotalSupply(tokenProtocolId);
}
else
......@@ -383,6 +396,8 @@ Display balance of "CRWS78Yf5kbWAyfcES6RfiTVzP87csPNhZzc" address
if (params.size() == 3)
{
uint64_t tokenProtocolId = StringToProtocolName(params[2].get_str().c_str());
if (tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
balance = NfTokensManager::Instance().BalanceOf(tokenProtocolId, filterKeyId);
}
else
......@@ -417,6 +432,8 @@ Examples:
NfTokenOwnerOfHelp();
uint64_t tokenProtocolId = StringToProtocolName(params[1].get_str().c_str());
if (tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
uint256 tokenId = ParseHashV(params[2].get_str(), "nfTokenId");
CKeyID ownerId = NfTokensManager::Instance().OwnerOf(tokenProtocolId, tokenId);
......
......@@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <spork.h>
#include "platform/nf-token/nf-token-protocol.h"
#include "platform/nf-token/nft-protocol-reg-tx-builder.h"
#include "platform/nf-token/nft-protocols-manager.h"
......@@ -14,6 +15,11 @@
json_spirit::Value nftproto(const json_spirit::Array& params, bool fHelp)
{
if (!IsSporkActive(SPORK_17_NFT_TX))
{
throw std::runtime_error("NFT spork is off");
}
std::string command = Platform::GetCommand(params, "usage: nftproto register|list|get|getbytxid|ownerof");
if (command == "register")
......@@ -143,12 +149,12 @@ Examples:
if (fHelp || params.empty() || params.size() > 5)
ListNftProtocolsHelp();
static const int defaultTxsCount = 20;
static const int defaultSkipFromTip = 0;
int count = (params.size() > 1) ? ParseInt32V(params[1], "count") : defaultTxsCount;
int skipFromTip = (params.size() > 2) ? ParseInt32V(params[2], "skipFromTip") : defaultSkipFromTip;
static const unsigned int defaultTxsCount = 20;
static const unsigned int defaultSkipFromTip = 0;
unsigned int count = (params.size() > 1) ? ParseUInt32V(params[1], "count") : defaultTxsCount;
unsigned int skipFromTip = (params.size() > 2) ? ParseUInt32V(params[2], "skipFromTip") : defaultSkipFromTip;
int height = (params.size() > 3 && params[3].get_str() != "*") ? ParseInt32V(params[3], "height") : chainActive.Height();
unsigned int height = (params.size() > 3 && params[3].get_str() != "*") ? ParseUInt32V(params[3], "height") : chainActive.Height();
if (height < 0 || height > chainActive.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height is out of range");
......@@ -293,6 +299,8 @@ Examples:
NftProtoOwnerOfHelp();
uint64_t tokenProtocolId = StringToProtocolName(params[1].get_str().c_str());
if (tokenProtocolId == NfToken::UNKNOWN_TOKEN_PROTOCOL)
throw JSONRPCError(RPC_INVALID_PARAMETER, "NFT protocol ID contains invalid characters");
CKeyID ownerId = NftProtocolsManager::Instance().OwnerOf(tokenProtocolId);
if (ownerId.IsNull())
......
......@@ -152,6 +152,24 @@ int32_t ParseInt32V(const Value& v, const std::string &strName)
return num;
}
uint32_t ParseUInt32V(const Value& v, const std::string &strName)
{
std::string strNum = v.get_str();
uint32_t num;
if (!ParseUInt32(strNum, &num))
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be a 32bit unsigned integer (not '"+strNum+"')");
return num;
}
uint8_t ParseUInt8V(const Value& v, const std::string &strName)
{
std::string strNum = v.get_str();
uint8_t num;
if (!ParseUInt8(strNum, &num))
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be an 8bit unsigned integer (not '"+strNum+"')");
return num;
}
bool ParseBoolV(const Value& v, const std::string &strName)
{
std::string strBool;
......
......@@ -126,6 +126,8 @@ extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::st
extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey);
extern int32_t ParseInt32V(const json_spirit::Value& v, const std::string &strName);
extern uint32_t ParseUInt32V(const json_spirit::Value& v, const std::string &strName);
extern uint8_t ParseUInt8V(const json_spirit::Value& v, const std::string &strName);
extern bool ParseBoolV(const json_spirit::Value& v, const std::string &strName);
extern void InitRPCMining();
......
......@@ -97,6 +97,7 @@ bool IsSporkActive(int nSporkID)
if(nSporkID == SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT) r = SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT_DEFAULT;
if(nSporkID == SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES) r = SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES_DEFAULT;
if(nSporkID == SPORK_16_DISCONNECT_OLD_NODES) r = SPORK_16_DISCONNECT_OLD_NODES_DEFAULT;
if(nSporkID == SPORK_17_NFT_TX) r = SPORK_17_NFT_TX_DEFAULT;
if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
}
......@@ -127,6 +128,7 @@ int64_t GetSporkValue(int nSporkID)
if(nSporkID == SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT) r = SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT_DEFAULT;
if(nSporkID == SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES) r = SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES_DEFAULT;
if(nSporkID == SPORK_16_DISCONNECT_OLD_NODES) r = SPORK_16_DISCONNECT_OLD_NODES_DEFAULT;
if(nSporkID == SPORK_17_NFT_TX) r = SPORK_17_NFT_TX_DEFAULT;
if(r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
}
......@@ -288,6 +290,7 @@ int CSporkManager::GetSporkIDByName(std::string strName)
if(strName == "SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT") return SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT;
if(strName == "SPORK_15_SYSTEMNODE_PAY_UPDATED_NODES") return SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES;
if(strName == "SPORK_16_DISCONNECT_OLD_NODES") return SPORK_16_DISCONNECT_OLD_NODES;
if(strName == "SPORK_17_NFT_TX") return SPORK_17_NFT_TX;
return -1;
}
......@@ -308,6 +311,7 @@ std::string CSporkManager::GetSporkNameByID(int id)
if(id == SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT) return "SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT";
if(id == SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES) return "SPORK_15_SYSTEMNODE_PAY_UPDATED_NODES";
if(id == SPORK_16_DISCONNECT_OLD_NODES) return "SPORK_16_DISCONNECT_OLD_NODES";
if(id == SPORK_17_NFT_TX) return "SPORK_17_NFT_TX";
return "Unknown";
}
......@@ -40,6 +40,7 @@ using namespace boost;
#define SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT 10013
#define SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES 10014
#define SPORK_16_DISCONNECT_OLD_NODES 10015
#define SPORK_17_NFT_TX 10016
#define SPORK_2_INSTANTX_DEFAULT 978307200 //2001-1-1
#define SPORK_3_INSTANTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18
......@@ -55,6 +56,7 @@ using namespace boost;
#define SPORK_14_SYSTEMNODE_PAYMENT_ENFORCEMENT_DEFAULT 4070908800 //OFF
#define SPORK_15_SYSTEMNODE_DONT_PAY_OLD_NODES_DEFAULT 4070908800 //OFF
#define SPORK_16_DISCONNECT_OLD_NODES_DEFAULT 4070908800 //OFF
#define SPORK_17_NFT_TX_DEFAULT 1582992203 //2020-2-29
class CSporkMessage;
class CSporkManager;
......
......@@ -435,6 +435,32 @@ bool ParseInt32(const std::string& str, int32_t *out)
n <= std::numeric_limits<int32_t>::max();
}
bool ParseUInt32(const std::string& str, uint32_t *out) {
char *endp = NULL;
errno = 0; // strtol will not set errno if valid
unsigned long int n = strtoul(str.c_str(), &endp, 10);
if(out)
*out = (unsigned int)n;
// Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
// platforms the size of these types may be different.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<uint32_t >::min() &&
n <= std::numeric_limits<uint32_t >::max();
}
bool ParseUInt8(const std::string& str, uint8_t *out) {
uint32_t internalOut;
if (!ParseUInt32(str, &internalOut)) {
return false;
}
if (out && internalOut >= std::numeric_limits<uint8_t >::min() && internalOut <= std::numeric_limits<uint8_t >::max()) {
*out = static_cast<uint8_t >(internalOut);
return true;
}
return false;
}
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
{
std::stringstream out;
......
......@@ -48,6 +48,8 @@ int atoi(const std::string& str);
* false if not the entire string could be parsed or when overflow or underflow occurred.
*/
bool ParseInt32(const std::string& str, int32_t *out);
bool ParseUInt32(const std::string& str, uint32_t *out);
bool ParseUInt8(const std::string& str, uint8_t *out);
template<typename T>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
......
......@@ -9,15 +9,15 @@
/**
* network protocol versioning
*/
static const int PROTOCOL_VERSION = 70058;
static const int PROTOCOL_VERSION = 70059;
static const int PROTOCOL_POS_START = 70057;
//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
//! disconnect from peers older than this proto version
static const int MIN_PEER_PROTO_VERSION_PREV = 70057;
static const int MIN_PEER_PROTO_VERSION_CURR = 70058;
static const int MIN_PEER_PROTO_VERSION_PREV = 70058;
static const int MIN_PEER_PROTO_VERSION_CURR = 70059;
//! minimum peer version accepted by legacySigner
static const int MIN_POOL_PEER_PROTO_VERSION = 70057;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment