text:
#include "serialize.h"
#include <boost/foreach.hpp>
#include "hash.h"
#include "util.h"
#include "database.h"
#include "main.h"
#include <algorithm>
#include "txdb.h"
#include "vm/vmrunevn.h"
#include "core.h"
#include "miner.h"
#include <boost/assign/list_of.hpp>
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
#include "json/json_spirit_writer_template.h"
using namespace json_spirit;

static bool GetKeyId(const CAccountViewCache &view, const vector<unsigned char> &ret,
		CKeyID &KeyId) {
	if (ret.size() == 6) {
		CRegID reg(ret);
		KeyId = reg.getKeyID(view);
	} else if (ret.size() == 34) {
		string addr(ret.begin(), ret.end());
		KeyId = CKeyID(addr);
	}else{
		return false;
	}
	if (KeyId.IsEmpty())
		return false;

	return true;
}

bool CID::Set(const CRegID &id) {
	CDataStream ds(SER_DISK, CLIENT_VERSION);
	ds << id;
	vchData.clear();
	vchData.insert(vchData.end(), ds.begin(), ds.end());
	return true;
}
bool CID::Set(const CKeyID &id) {
	vchData.resize(20);
	memcpy(&vchData[0], &id, 20);
	return true;
}
bool CID::Set(const CPubKey &id) {
	vchData.resize(id.size());
	memcpy(&vchData[0], &id, id.size());
	return true;
}
bool CID::Set(const CNullID &id) {
	return true;
}
bool CID::Set(const CUserID &userid) {
	return boost::apply_visitor(CIDVisitor(this), userid);
}
CUserID CID::GetUserId() {
	if (1< vchData.size() && vchData.size() <= 10) {
		CRegID regId;
		regId.SetRegIDByCompact(vchData);
		return CUserID(regId);
	} else if (vchData.size() == 33) {
		CPubKey pubKey(vchData);
		return CUserID(pubKey);
	} else if (vchData.size() == 20) {
		uint160 data = uint160(vchData);
		CKeyID keyId(data);
		return CUserID(keyId);
	} else if(vchData.empty()) {
		return CNullID();
	}
	else {
		LogPrint("ERROR", "vchData:%s, len:%d\n", HexStr(vchData).c_str(), vchData.size());
		throw ios_base::failure("GetUserId error from CID");
	}
	return CNullID();
}

bool CRegID::clean()  {
	nHeight = 0 ;
	nIndex = 0 ;
	vRegID.clear();
	return true;
}
CRegID::CRegID(const vector<unsigned char>& vIn) {
	assert(vIn.size() == 6);
	vRegID = vIn;
	nHeight = 0;
	nIndex = 0;
	CDataStream ds(vIn, SER_DISK, CLIENT_VERSION);
	ds >> nHeight;
	ds >> nIndex;
}
bool CRegID::IsSimpleRegIdStr(const string & str)
{
	int len = str.length();
	if (len >= 3) {
		int pos = str.find('-');

		if (pos > len - 1) {
			return false;
		}
		string firtstr = str.substr(0, pos);

		if (firtstr.length() > 10 || firtstr.length() == 0) //int max is 4294967295 can not over 10
			return false;

		for (auto te : firtstr) {
			if (!isdigit(te))
				return false;
		}
		string endstr = str.substr(pos + 1);
		if (endstr.length() > 10 || endstr.length() == 0) //int max is 4294967295 can not over 10
			return false;
		for (auto te : endstr) {
			if (!isdigit(te))
				return false;
		}
		return true;
	}
	return false;
}
bool CRegID::GetKeyID(const string & str,CKeyID &keyId)
{
	CRegID te(str);
	if(te.IsEmpty())
		return false;
	keyId = te.getKeyID(*pAccountViewTip);
	return !keyId.IsEmpty();
}
bool CRegID::IsRegIdStr(const string & str)
 {
	if(IsSimpleRegIdStr(str)){
		return true;
	}
	else if(str.length()==12){
		return true;
	}
	return false;
}
void CRegID::SetRegID(string strRegID){
	nHeight = 0;
	nIndex = 0;
	vRegID.clear();

	if(IsSimpleRegIdStr(strRegID))
	{
		int pos = strRegID.find('-');
		nHeight = atoi(strRegID.substr(0, pos).c_str());
		nIndex = atoi(strRegID.substr(pos+1).c_str());
		vRegID.insert(vRegID.end(), BEGIN(nHeight), END(nHeight));
		vRegID.insert(vRegID.end(), BEGIN(nIndex), END(nIndex));
//		memcpy(&vRegID.at(0),&nHeight,sizeof(nHeight));
//		memcpy(&vRegID[sizeof(nHeight)],&nIndex,sizeof(nIndex));
	}
	else if(strRegID.length()==12)
	{
		vRegID = ::ParseHex(strRegID);
		memcpy(&nHeight,&vRegID[0],sizeof(nHeight));
		memcpy(&nIndex,&vRegID[sizeof(nHeight)],sizeof(nIndex));
	}
}
void CRegID::SetRegID(const vector<unsigned char>& vIn) {
	assert(vIn.size() == 6);
	vRegID = vIn;
	CDataStream ds(vIn, SER_DISK, CLIENT_VERSION);
	ds >> nHeight;
	ds >> nIndex;
}
CRegID::CRegID(string strRegID) {
	SetRegID(strRegID);
}
CRegID::CRegID(uint32_t nHeightIn, uint16_t nIndexIn) {
	nHeight = nHeightIn;
	nIndex = nIndexIn;
	vRegID.clear();
	vRegID.insert(vRegID.end(), BEGIN(nHeightIn), END(nHeightIn));
	vRegID.insert(vRegID.end(), BEGIN(nIndexIn), END(nIndexIn));
}
string CRegID::ToString() const {
//	if(!IsEmpty())
//	return ::HexStr(vRegID);
	if(!IsEmpty())
	  return  strprintf("%d-%d",nHeight,nIndex);
	return string(" ");
}
CKeyID CRegID::getKeyID(const CAccountViewCache &view)const
{
	CKeyID ret;
	CAccountViewCache(view).GetKeyId(*this,ret);
	return ret;
}
void CRegID::SetRegIDByCompact(const vector<unsigned char> &vIn) {
	if(vIn.size()>0)
	{
		CDataStream ds(vIn, SER_DISK, CLIENT_VERSION);
		ds >> *this;
	}
	else
	{
		clean();
	}
}

bool CBaseTransaction::IsValidHeight(int nCurHeight, int nTxCacheHeight) const
{
	if(REWARD_TX == nTxType)
		return true;
	if (nValidHeight > nCurHeight + nTxCacheHeight / 2)
			return false;
	if (nValidHeight < nCurHeight - nTxCacheHeight / 2)
			return false;
	return true;
}
bool CBaseTransaction::UndoExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	vector<CAccountLog>::reverse_iterator rIterAccountLog = txundo.vAccountLog.rbegin();
	for (; rIterAccountLog != txundo.vAccountLog.rend(); ++rIterAccountLog) {
		CAccount account;
		CUserID userId = rIterAccountLog->keyID;
		if (!view.GetAccount(userId, account)) {
			return state.DoS(100, ERRORMSG("UndoExecuteTx() : CBaseTransaction UndoExecuteTx, undo ExecuteTx read accountId= %s account info error"),
					UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
		}
		if (!account.UndoOperateAccount(*rIterAccountLog)) {
			return state.DoS(100, ERRORMSG("UndoExecuteTx() : CBaseTransaction UndoExecuteTx, undo UndoOperateAccount failed"), UPDATE_ACCOUNT_FAIL,
					"undo-operate-account-failed");
		}
		if (COMMON_TX == nTxType
				&& (account.IsEmptyValue()
						&& (!account.PublicKey.IsFullyValid() || account.PublicKey.GetKeyID() != account.keyID))) {
			view.EraseAccount(userId);
		} else {
			if (!view.SetAccount(userId, account)) {
				return state.DoS(100,
						ERRORMSG("UndoExecuteTx() : CBaseTransaction UndoExecuteTx, undo ExecuteTx write accountId= %s account info error"),
						UPDATE_ACCOUNT_FAIL, "bad-write-accountdb");
			}
		}
	}
	vector<CScriptDBOperLog>::reverse_iterator rIterScriptDBLog = txundo.vScriptOperLog.rbegin();
	for (; rIterScriptDBLog != txundo.vScriptOperLog.rend(); ++rIterScriptDBLog) {
		if (!scriptDB.UndoScriptData(rIterScriptDBLog->vKey, rIterScriptDBLog->vValue))
			return state.DoS(100, ERRORMSG("UndoExecuteTx() : CBaseTransaction UndoExecuteTx, undo scriptdb data error"), UPDATE_ACCOUNT_FAIL,
					"bad-save-scriptdb");
	}
	if(CONTRACT_TX == nTxType) {
		if (!scriptDB.EraseTxRelAccout(GetHash()))
			return state.DoS(100, ERRORMSG("UndoExecuteTx() : CBaseTransaction UndoExecuteTx, erase tx rel account error"), UPDATE_ACCOUNT_FAIL,
							"bad-save-scriptdb");
	}
	return true;
}
uint64_t CBaseTransaction::GetFuel(int nfuelRate) {
	uint64_t llFuel = ceil(nRunStep/100.0f) * nfuelRate;
	if(REG_APP_TX == nTxType) {
		if (chainActive.Tip()->nHeight > nRegAppFuel2FeeForkHeight) {
			llFuel = 0;
		} else {
			if (llFuel < 1 * COIN) {
				llFuel = 1 * COIN;
			}
		}
	}
	return llFuel;
}

string CBaseTransaction::txTypeArray[6] = { "NULL_TXTYPE", "REWARD_TX", "REG_ACCT_TX", "COMMON_TX", "CONTRACT_TX", "REG_APP_TX"};

int CBaseTransaction::GetFuelRate(CScriptDBViewCache &scriptDB) {
	if(0 == nFuelRate) {
		CDiskTxPos postx;
		if (scriptDB.ReadTxIndex(GetHash(), postx)) {
			CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
			CBlockHeader header;
			try {
				file >> header;
			} catch (std::exception &e) {
				return ERRORMSG("%s : Deserialize or I/O error - %s", __func__, e.what());
			}
			nFuelRate = header.GetFuelRate();
		}
		else {
			nFuelRate = GetElementForBurn(chainActive.Tip());
		}
	}
	return nFuelRate;
}

bool CRegisterAccountTx::ExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	CAccount account;
	CRegID regId(nHeight, nIndex);
	CKeyID keyId = boost::get<CPubKey>(userId).GetKeyID();
	if (!view.GetAccount(userId, account))
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, read source keyId %s account info error", keyId.ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	CAccountLog acctLog(account);
	if(account.PublicKey.IsFullyValid() && account.PublicKey.GetKeyID() == keyId) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, read source keyId %s duplicate register", keyId.ToString()),
					UPDATE_ACCOUNT_FAIL, "duplicate-register-account");
	}
	account.PublicKey = boost::get<CPubKey>(userId);
	if (llFees > 0) {
		if(!account.OperateAccount(MINUS_FREE, llFees, nHeight))
			return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, not sufficient funds in account, keyid=%s", keyId.ToString()),
					UPDATE_ACCOUNT_FAIL, "not-sufficiect-funds");
	}

	account.regID = regId;
	if (typeid(CPubKey) == minerId.type()) {
		account.MinerPKey = boost::get<CPubKey>(minerId);
		if (account.MinerPKey.IsValid() && !account.MinerPKey.IsFullyValid()) {
			return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, MinerPKey:%s Is Invalid", account.MinerPKey.ToString()),
					UPDATE_ACCOUNT_FAIL, "MinerPKey Is Invalid");
		}
	}

	if (!view.SaveAccountInfo(regId, keyId, account)) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, write source addr %s account info error", regId.ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	}
	txundo.vAccountLog.push_back(acctLog);
	txundo.txHash = GetHash();
	if(SysCfg().GetAddressToTxFlag()) {
		CScriptDBOperLog operAddressToTxLog;
		CKeyID sendKeyId;
		if(!view.GetKeyId(userId, sendKeyId)) {
			return ERRORMSG("ExecuteTx() : CRegisterAccountTx ExecuteTx, get keyid by userId error!");
		}
		if(!scriptDB.SetTxHashByAddress(sendKeyId, nHeight, nIndex+1, txundo.txHash.GetHex(), operAddressToTxLog))
			return false;
		txundo.vScriptOperLog.push_back(operAddressToTxLog);
	}
	return true;
}
bool CRegisterAccountTx::UndoExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state,
		CTxUndo &txundo, int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	//drop account
	CRegID accountId(nHeight, nIndex);
	CAccount oldAccount;
	if (!view.GetAccount(accountId, oldAccount))
		return state.DoS(100,
				ERRORMSG("ExecuteTx() : CRegisterAccountTx UndoExecuteTx, read secure account=%s info error", accountId.ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	CKeyID keyId;
	view.GetKeyId(accountId, keyId);

	if (llFees > 0) {
		CAccountLog accountLog;
		if (!txundo.GetAccountOperLog(keyId, accountLog))
			return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAccountTx UndoExecuteTx, read keyId=%s tx undo info error", keyId.GetHex()),
					UPDATE_ACCOUNT_FAIL, "bad-read-txundoinfo");
		oldAccount.UndoOperateAccount(accountLog);
	}

	if (!oldAccount.IsEmptyValue()) {
		CPubKey empPubKey;
		oldAccount.PublicKey = empPubKey;
		oldAccount.MinerPKey = empPubKey;
		CUserID userId(keyId);
		view.SetAccount(userId, oldAccount);
	} else {
		view.EraseAccount(userId);
	}
	view.EraseId(accountId);
	return true;
}
bool CRegisterAccountTx::GetAddress(set<CKeyID> &vAddr, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {
	if (!boost::get<CPubKey>(userId).IsFullyValid()) {
		return false;
	}
	vAddr.insert(boost::get<CPubKey>(userId).GetKeyID());
	return true;
}
string CRegisterAccountTx::ToString(CAccountViewCache &view) const {
	string str;
	str += strprintf("txType=%s, hash=%s, ver=%d, pubkey=%s, llFees=%ld, keyid=%s, nValidHeight=%d\n",
	txTypeArray[nTxType],GetHash().ToString().c_str(), nVersion, boost::get<CPubKey>(userId).ToString(), llFees, boost::get<CPubKey>(userId).GetKeyID().ToAddress(), nValidHeight);
	return str;
}
Object CRegisterAccountTx::ToJSON(const CAccountViewCache &AccountView) const{
	Object result;

	result.push_back(Pair("hash", GetHash().GetHex()));
	result.push_back(Pair("txtype", txTypeArray[nTxType]));
	result.push_back(Pair("ver", nVersion));
	result.push_back(Pair("addr", boost::get<CPubKey>(userId).GetKeyID().ToAddress()));
	CID id(userId);
	CID minerIdTemp(minerId);
	result.push_back(Pair("pubkey", HexStr(id.GetID())));
	result.push_back(Pair("miner_pubkey", HexStr(minerIdTemp.GetID())));
	result.push_back(Pair("fees", llFees));
	result.push_back(Pair("height", nValidHeight));
   return result;
}
bool CRegisterAccountTx::CheckTransction(CValidationState &state, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {

	if (userId.type() != typeid(CPubKey)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx userId must be CPubKey"), REJECT_INVALID,
				"userid-type-error");
	}

	if ((minerId.type() != typeid(CPubKey)) && (minerId.type() != typeid(CNullID))) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx minerId must be CPubKey or CNullID"), REJECT_INVALID,
				"minerid-type-error");
	}

	//check pubKey valid
	if (!boost::get<CPubKey>(userId).IsFullyValid()) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAccountTx CheckTransction, register tx public key is invalid"), REJECT_INVALID,
				"bad-regtx-publickey");
	}

	//check signature script
	uint256 sighash = SignatureHash();
	if(!CheckSignScript(sighash, signature, boost::get<CPubKey>(userId))) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAccountTx CheckTransction, register tx signature error "), REJECT_INVALID,
				"bad-regtx-signature");
	}

	if (!MoneyRange(llFees))
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAccountTx CheckTransction, register tx fee out of range"), REJECT_INVALID,
				"bad-regtx-fee-toolarge");
	return true;
}

uint256 CRegisterAccountTx::GetHash() const {
	return SignatureHash();
}
uint256 CRegisterAccountTx::SignatureHash() const {
	CHashWriter ss(SER_GETHASH, 0);
	CID userPubkey(userId);
	CID minerPubkey(minerId);
	ss << VARINT(nVersion) << nTxType << VARINT(nValidHeight) << userPubkey << minerPubkey << VARINT(llFees);
	return ss.GetHash();
}

bool CTransaction::ExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	CAccount srcAcct;
	CAccount desAcct;
	CAccountLog desAcctLog;
	uint64_t minusValue = llFees+llValues;
	if (!view.GetAccount(srcRegId, srcAcct))
		return state.DoS(100,
				ERRORMSG("ExecuteTx() : CTransaction ExecuteTx, read source addr %s account info error", boost::get<CRegID>(srcRegId).ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	CAccountLog srcAcctLog(srcAcct);
	if (!srcAcct.OperateAccount(MINUS_FREE, minusValue, nHeight))
		return state.DoS(100, ERRORMSG("ExecuteTx() : CTransaction ExecuteTx, accounts insufficient funds"), UPDATE_ACCOUNT_FAIL,
				"operate-minus-account-failed");
	CUserID userId = srcAcct.keyID;
	if(!view.SetAccount(userId, srcAcct)){
		return state.DoS(100, ERRORMSG("UpdataAccounts() :CTransaction ExecuteTx, save account%s info error",  boost::get<CRegID>(srcRegId).ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-write-accountdb");
	}

	uint64_t addValue = llValues;
	if(!view.GetAccount(desUserId, desAcct)) {
		if((COMMON_TX == nTxType) && (desUserId.type() == typeid(CKeyID))) {
			desAcct.keyID = boost::get<CKeyID>(desUserId);
			desAcctLog.keyID = desAcct.keyID;
		}
		else {
			return state.DoS(100, ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, get account info failed by regid:%s", boost::get<CRegID>(desUserId).ToString()), UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
		}
	}
	else{
		desAcctLog.SetValue(desAcct);
	}
	if (!desAcct.OperateAccount(ADD_FREE, addValue, nHeight)) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CTransaction ExecuteTx, operate accounts error"), UPDATE_ACCOUNT_FAIL,
				"operate-add-account-failed");
	}
	if (!view.SetAccount(desUserId, desAcct)) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CTransaction ExecuteTx, save account error, kyeId=%s", desAcct.keyID.ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-save-account");
	}
	txundo.vAccountLog.push_back(srcAcctLog);
	txundo.vAccountLog.push_back(desAcctLog);

	if (CONTRACT_TX == nTxType) {

		vector<unsigned char> vScript;
		if(!scriptDB.GetScript(boost::get<CRegID>(desUserId), vScript)) {
			return state.DoS(100, ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, read account faild, RegId=%s", boost::get<CRegID>(desUserId).ToString()),
						UPDATE_ACCOUNT_FAIL, "bad-read-account");
		}
		CVmRunEvn vmRunEvn;
		std::shared_ptr<CBaseTransaction> pTx = GetNewInstance();
		uint64_t el = GetFuelRate(scriptDB);
		int64_t llTime = GetTimeMillis();
		tuple<bool, uint64_t, string> ret = vmRunEvn.run(pTx, view, scriptDB, nHeight, el, nRunStep);
		if (!std::get<0>(ret))
			return state.DoS(100,
					ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, txhash=%s run script error:%s",
							GetHash().GetHex(), std::get<2>(ret)), UPDATE_ACCOUNT_FAIL, "run-script-error");
		LogPrint("CONTRACT_TX", "execute contract elapse:%lld, txhash=%s\n", GetTimeMillis() - llTime,
				GetHash().GetHex());
		set<CKeyID> vAddress;
		vector<std::shared_ptr<CAccount> > &vAccount = vmRunEvn.GetNewAccont();
		for (auto & itemAccount : vAccount) {
			vAddress.insert(itemAccount->keyID);
			userId = itemAccount->keyID;
			CAccount oldAcct;
			if(!view.GetAccount(userId, oldAcct)) {
				if(!itemAccount->keyID.IsNull()) {
					oldAcct.keyID = itemAccount->keyID;
				}else {
					return state.DoS(100,
							ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, read account info error"),
							UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
				}
			}
			CAccountLog oldAcctLog(oldAcct);
			if (!view.SetAccount(userId, *itemAccount))
				return state.DoS(100,
						ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, write account info error"),
						UPDATE_ACCOUNT_FAIL, "bad-write-accountdb");
			txundo.vAccountLog.push_back(oldAcctLog);
		}
		txundo.vScriptOperLog.insert(txundo.vScriptOperLog.end(), vmRunEvn.GetDbLog()->begin(), vmRunEvn.GetDbLog()->end());
		vector<std::shared_ptr<CAppUserAccout> > &vAppUserAccount = vmRunEvn.GetRawAppUserAccount();
		for (auto & itemUserAccount : vAppUserAccount) {
			CKeyID itemKeyID;
			bool bValid = GetKeyId(view, itemUserAccount.get()->getaccUserId(), itemKeyID);
			if(bValid) {
				vAddress.insert(itemKeyID);
			}
		}
		if(!scriptDB.SetTxRelAccout(GetHash(), vAddress))
				return ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, save tx relate account info to script db error");

	}
	txundo.txHash = GetHash();

	if(SysCfg().GetAddressToTxFlag()) {
		CScriptDBOperLog operAddressToTxLog;
		CKeyID sendKeyId;
		CKeyID revKeyId;
		if(!view.GetKeyId(srcRegId, sendKeyId)) {
			return ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, get keyid by srcRegId error!");
		}
		if(!view.GetKeyId(desUserId, revKeyId)) {
			return ERRORMSG("ExecuteTx() : ContractTransaction ExecuteTx, get keyid by desUserId error!");
		}
		if(!scriptDB.SetTxHashByAddress(sendKeyId, nHeight, nIndex+1, txundo.txHash.GetHex(), operAddressToTxLog))
			return false;
		txundo.vScriptOperLog.push_back(operAddressToTxLog);
		if(!scriptDB.SetTxHashByAddress(revKeyId, nHeight, nIndex+1, txundo.txHash.GetHex(), operAddressToTxLog))
			return false;
		txundo.vScriptOperLog.push_back(operAddressToTxLog);
	}

	return true;
}
bool CTransaction::GetAddress(set<CKeyID> &vAddr, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {
	CKeyID keyId;
	if (!view.GetKeyId(srcRegId, keyId))
		return false;

	vAddr.insert(keyId);
	CKeyID desKeyId;
	if (!view.GetKeyId(desUserId, desKeyId))
		return false;
	vAddr.insert(desKeyId);

	if (CONTRACT_TX == nTxType) {
		CVmRunEvn vmRunEvn;
		std::shared_ptr<CBaseTransaction> pTx = GetNewInstance();
		uint64_t el = GetFuelRate(scriptDB);
		CScriptDBViewCache scriptDBView(scriptDB, true);
		if (uint256() == pTxCacheTip->IsContainTx(GetHash())) {
			CAccountViewCache accountView(view, true);
			tuple<bool, uint64_t, string> ret = vmRunEvn.run(pTx, accountView, scriptDBView, chainActive.Height() + 1, el,
					nRunStep);
			if (!std::get<0>(ret))
				return ERRORMSG("GetAddress()  : %s", std::get<2>(ret));

			vector<shared_ptr<CAccount> > vpAccount = vmRunEvn.GetNewAccont();

			for (auto & item : vpAccount) {
				vAddr.insert(item->keyID);
			}
			vector<std::shared_ptr<CAppUserAccout> > &vAppUserAccount = vmRunEvn.GetRawAppUserAccount();
			for (auto & itemUserAccount : vAppUserAccount) {
				CKeyID itemKeyID;
				bool bValid = GetKeyId(view, itemUserAccount.get()->getaccUserId(), itemKeyID);
				if(bValid) {
					vAddr.insert(itemKeyID);
				}
			}
		} else {
			set<CKeyID> vTxRelAccount;
			if (!scriptDBView.GetTxRelAccount(GetHash(), vTxRelAccount))
				return false;
			vAddr.insert(vTxRelAccount.begin(), vTxRelAccount.end());
		}
	}
	return true;
}
string CTransaction::ToString(CAccountViewCache &view) const {
	string str;
	string desId;
	if (desUserId.type() == typeid(CKeyID)) {
		desId = boost::get<CKeyID>(desUserId).ToString();
	} else if (desUserId.type() == typeid(CRegID)) {
		desId = boost::get<CRegID>(desUserId).ToString();
	}
	str += strprintf("txType=%s, hash=%s, ver=%d, srcId=%s desId=%s, llFees=%ld, vContract=%s, nValidHeight=%d\n",
	txTypeArray[nTxType], GetHash().ToString().c_str(), nVersion, boost::get<CRegID>(srcRegId).ToString(), desId.c_str(), llFees, HexStr(vContract).c_str(), nValidHeight);
	return str;
}

Object CTransaction::ToJSON(const CAccountViewCache &AccountView) const{
	Object result;
	CAccountViewCache view(AccountView);
    CKeyID keyid;

	auto getregidstring = [&](CUserID const &userId) {
		if(userId.type() == typeid(CRegID))
			return boost::get<CRegID>(userId).ToString();
		return string(" ");
	};

	result.push_back(Pair("hash", GetHash().GetHex()));
	result.push_back(Pair("txtype", txTypeArray[nTxType]));
	result.push_back(Pair("ver", nVersion));
	result.push_back(Pair("regid",  getregidstring(srcRegId)));
	view.GetKeyId(srcRegId, keyid);
	result.push_back(Pair("addr",  keyid.ToAddress()));
	result.push_back(Pair("desregid", getregidstring(desUserId)));
	view.GetKeyId(desUserId, keyid);
	result.push_back(Pair("desaddr", keyid.ToAddress()));
	result.push_back(Pair("money", llValues));
	result.push_back(Pair("fees", llFees));
	result.push_back(Pair("height", nValidHeight));
	result.push_back(Pair("Contract", HexStr(vContract)));
    return result;
}
bool CTransaction::CheckTransction(CValidationState &state, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {

	if(srcRegId.type() != typeid(CRegID)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CTransaction srcRegId must be CRegID"), REJECT_INVALID, "srcaddr-type-error");
	}

	if((desUserId.type() != typeid(CRegID)) && (desUserId.type() != typeid(CKeyID))) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CTransaction desUserId must be CRegID or CKeyID"), REJECT_INVALID, "desaddr-type-error");
	}

	if (!MoneyRange(llFees)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CTransaction CheckTransction, appeal tx fee out of range"), REJECT_INVALID,
				"bad-appeal-fee-toolarge");
	}

	CAccount acctInfo;
	if (!view.GetAccount(boost::get<CRegID>(srcRegId), acctInfo)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() :CTransaction CheckTransction, read account falied, regid=%s", boost::get<CRegID>(srcRegId).ToString()), REJECT_INVALID, "bad-getaccount");
	}
	if (!acctInfo.IsRegister()) {
		return state.DoS(100, ERRORMSG("CheckTransaction(): CTransaction CheckTransction, account have not registed public key"), REJECT_INVALID,
				"bad-no-pubkey");
	}

	uint256 sighash = SignatureHash();
	if (!CheckSignScript(sighash, signature, acctInfo.PublicKey)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CTransaction CheckTransction, CheckSignScript failed"), REJECT_INVALID,
				"bad-signscript-check");
	}

	return true;
}
uint256 CTransaction::GetHash() const {
	return SignatureHash();
}
uint256 CTransaction::SignatureHash() const {
	CHashWriter ss(SER_GETHASH, 0);
	CID srcId(srcRegId);
	CID desId(desUserId);
	ss << VARINT(nVersion) << nTxType << VARINT(nValidHeight) << srcId << desId << VARINT(llFees) << VARINT(llValues) << vContract;
	return ss.GetHash();
}

bool CRewardTransaction::ExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {

	CID id(account);
	if (account.type() != typeid(CRegID)) {
		return state.DoS(100,
				ERRORMSG("ExecuteTx() : CRewardTransaction ExecuteTx, account %s error, data type must be either CRegID", HexStr(id.GetID())),
				UPDATE_ACCOUNT_FAIL, "bad-account");
	}
	CAccount acctInfo;
	if (!view.GetAccount(account, acctInfo)) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRewardTransaction ExecuteTx, read source addr %s account info error", HexStr(id.GetID())),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	}
//	LogPrint("op_account", "before operate:%s\n", acctInfo.ToString());
	CAccountLog acctInfoLog(acctInfo);
	if(0 == nIndex) {   //current block reward tx, need to clear coindays
		acctInfo.ClearAccPos(nHeight);
	}
	else if(-1 == nIndex){ //maturity reward tx,only update values
		acctInfo.llValues += rewardValue;
	}
	else {  //never go into this step
		return ERRORMSG("nIndex type error!");
//		assert(0);
	}

	CUserID userId = acctInfo.keyID;
	if (!view.SetAccount(userId, acctInfo))
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRewardTransaction ExecuteTx, write secure account info error"), UPDATE_ACCOUNT_FAIL,
				"bad-save-accountdb");
	txundo.Clear();
	txundo.vAccountLog.push_back(acctInfoLog);
	txundo.txHash = GetHash();
	if(SysCfg().GetAddressToTxFlag() && 0 == nIndex) {
		CScriptDBOperLog operAddressToTxLog;
		CKeyID sendKeyId;
		if(!view.GetKeyId(account, sendKeyId)) {
			return ERRORMSG("ExecuteTx() : CRewardTransaction ExecuteTx, get keyid by account error!");
		}
		if(!scriptDB.SetTxHashByAddress(sendKeyId, nHeight, nIndex+1, txundo.txHash.GetHex(), operAddressToTxLog))
			return false;
		txundo.vScriptOperLog.push_back(operAddressToTxLog);
	}
//	LogPrint("op_account", "after operate:%s\n", acctInfo.ToString());
	return true;
}
bool CRewardTransaction::GetAddress(set<CKeyID> &vAddr, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {
	CKeyID keyId;
	if (account.type() == typeid(CRegID)) {
		if (!view.GetKeyId(account, keyId))
			return false;
		vAddr.insert(keyId);
	} else if (account.type() == typeid(CPubKey)) {
		CPubKey pubKey = boost::get<CPubKey>(account);
		if (!pubKey.IsFullyValid())
			return false;
		vAddr.insert(pubKey.GetKeyID());
	}
	return true;
}
string CRewardTransaction::ToString(CAccountViewCache &view) const {
	string str;
	CKeyID keyId;
	view.GetKeyId(account, keyId);
	CRegID regId;
	view.GetRegId(account, regId);
	str += strprintf("txType=%s, hash=%s, ver=%d, account=%s, keyid=%s, rewardValue=%ld\n", txTypeArray[nTxType], GetHash().ToString().c_str(), nVersion, regId.ToString(), keyId.GetHex(), rewardValue);
	return str;
}
Object CRewardTransaction::ToJSON(const CAccountViewCache &AccountView) const{
	Object result;
	CAccountViewCache view(AccountView);
    CKeyID keyid;
	result.push_back(Pair("hash", GetHash().GetHex()));
	result.push_back(Pair("txtype", txTypeArray[nTxType]));
	result.push_back(Pair("ver", nVersion));
	if(account.type() == typeid(CRegID)) {
		result.push_back(Pair("regid", boost::get<CRegID>(account).ToString()));
	}
	if(account.type() == typeid(CPubKey)) {
		result.push_back(Pair("pubkey", boost::get<CPubKey>(account).ToString()));
	}
	view.GetKeyId(account, keyid);
	result.push_back(Pair("addr", keyid.ToAddress()));
	result.push_back(Pair("money", rewardValue));
	result.push_back(Pair("height", nHeight));
	return std::move(result);
}
bool CRewardTransaction::CheckTransction(CValidationState &state, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {
	return true;
}
uint256 CRewardTransaction::GetHash() const
{
	return SignatureHash();
}
uint256 CRewardTransaction::SignatureHash() const {
	CHashWriter ss(SER_GETHASH, 0);
	CID accId(account);
	ss << VARINT(nVersion) << nTxType << accId << VARINT(rewardValue) << VARINT(nHeight);
	return ss.GetHash();
}

bool CRegisterAppTx::ExecuteTx(int nIndex, CAccountViewCache &view,CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	CID id(regAcctId);
	CAccount acctInfo;
	CScriptDBOperLog operLog;
	if (!view.GetAccount(regAcctId, acctInfo)) {
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx, read regist addr %s account info error", HexStr(id.GetID())),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	}
	CAccount acctInfoLog(acctInfo);
	uint64_t minusValue = llFees;
	if (minusValue > 0) {
		if(!acctInfo.OperateAccount(MINUS_FREE, minusValue, nHeight))
			return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx, operate account failed ,regId=%s", boost::get<CRegID>(regAcctId).ToString()),
					UPDATE_ACCOUNT_FAIL, "operate-account-failed");
		txundo.vAccountLog.push_back(acctInfoLog);
	}
	txundo.txHash = GetHash();

	CVmScript vmScript;
	CDataStream stream(script, SER_DISK, CLIENT_VERSION);
	try {
		stream >> vmScript;
	} catch (exception& e) {
		return state.DoS(100, ERRORMSG(("ExecuteTx() :CRegisterAppTx ExecuteTx, Unserialize to vmScript error:" + string(e.what())).c_str()),
				UPDATE_ACCOUNT_FAIL, "unserialize-script-error");
	}
	if(!vmScript.IsValid())
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx, vmScript invalid"), UPDATE_ACCOUNT_FAIL, "script-check-failed");

	CRegID regId(nHeight, nIndex);
	//create script account
	CKeyID keyId = Hash160(regId.GetVec6());
	CAccount account;
	account.keyID = keyId;
	account.regID = regId;
	//save new script content
	if(!scriptDB.SetScript(regId, script)){
		return state.DoS(100,
				ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx, save script id %s script info error", regId.ToString()),
				UPDATE_ACCOUNT_FAIL, "bad-save-scriptdb");
	}
	if (!view.SaveAccountInfo(regId, keyId, account)) {
		return state.DoS(100,
				ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx create new account script id %s script info error",
						regId.ToString()), UPDATE_ACCOUNT_FAIL, "bad-save-scriptdb");
	}

	nRunStep = script.size();

	if(!operLog.vKey.empty()) {
		txundo.vScriptOperLog.push_back(operLog);
	}
	CUserID userId = acctInfo.keyID;
	if (!view.SetAccount(userId, acctInfo))
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAppTx ExecuteTx, save account info error"), UPDATE_ACCOUNT_FAIL,
				"bad-save-accountdb");

	if(SysCfg().GetAddressToTxFlag()) {
		CScriptDBOperLog operAddressToTxLog;
		CKeyID sendKeyId;
		if(!view.GetKeyId(regAcctId, sendKeyId)) {
			return ERRORMSG("ExecuteTx() : CRewardTransaction ExecuteTx, get regAcctId by account error!");
		}
		if(!scriptDB.SetTxHashByAddress(sendKeyId, nHeight, nIndex+1, txundo.txHash.GetHex(), operAddressToTxLog))
			return false;
		txundo.vScriptOperLog.push_back(operAddressToTxLog);
	}
	return true;
}
bool CRegisterAppTx::UndoExecuteTx(int nIndex, CAccountViewCache &view, CValidationState &state, CTxUndo &txundo,
		int nHeight, CTransactionDBCache &txCache, CScriptDBViewCache &scriptDB) {
	CID id(regAcctId);
	CAccount account;
	CUserID userId;
	if (!view.GetAccount(regAcctId, account)) {
		return state.DoS(100, ERRORMSG("UndoUpdateAccount() : CRegisterAppTx UndoExecuteTx, read regist addr %s account info error", HexStr(id.GetID())),
				UPDATE_ACCOUNT_FAIL, "bad-read-accountdb");
	}

	if(script.size() != 6) {

		CRegID scriptId(nHeight, nIndex);
		//delete script content
		if (!scriptDB.EraseScript(scriptId)) {
			return state.DoS(100, ERRORMSG("UndoUpdateAccount() : CRegisterAppTx UndoExecuteTx, erase script id %s error", scriptId.ToString()),
					UPDATE_ACCOUNT_FAIL, "erase-script-failed");
		}
		//delete account
		if(!view.EraseId(scriptId)){
			return state.DoS(100, ERRORMSG("UndoUpdateAccount() : CRegisterAppTx UndoExecuteTx, erase script account %s error", scriptId.ToString()),
								UPDATE_ACCOUNT_FAIL, "erase-appkeyid-failed");
		}
		CKeyID keyId = Hash160(scriptId.GetVec6());
		userId = keyId;
		if(!view.EraseAccount(userId)){
			return state.DoS(100, ERRORMSG("UndoUpdateAccount() : CRegisterAppTx UndoExecuteTx, erase script account %s error", scriptId.ToString()),
								UPDATE_ACCOUNT_FAIL, "erase-appaccount-failed");
		}
//		LogPrint("INFO", "Delete regid %s app account\n", scriptId.ToString());
	}

	for(auto &itemLog : txundo.vAccountLog){
		if(itemLog.keyID == account.keyID) {
			if(!account.UndoOperateAccount(itemLog))
				return state.DoS(100, ERRORMSG("UndoUpdateAccount: CRegisterAppTx UndoExecuteTx, undo operate account error, keyId=%s", account.keyID.ToString()),
						UPDATE_ACCOUNT_FAIL, "undo-account-failed");
		}
	}

	vector<CScriptDBOperLog>::reverse_iterator rIterScriptDBLog = txundo.vScriptOperLog.rbegin();
	for(; rIterScriptDBLog != txundo.vScriptOperLog.rend(); ++rIterScriptDBLog) {
		if(!scriptDB.UndoScriptData(rIterScriptDBLog->vKey, rIterScriptDBLog->vValue))
			return state.DoS(100,
					ERRORMSG("ExecuteTx() : CRegisterAppTx UndoExecuteTx, undo scriptdb data error"), UPDATE_ACCOUNT_FAIL, "undo-scriptdb-failed");
	}
	userId = account.keyID;
	if (!view.SetAccount(userId, account))
		return state.DoS(100, ERRORMSG("ExecuteTx() : CRegisterAppTx UndoExecuteTx, save account error"), UPDATE_ACCOUNT_FAIL,
				"bad-save-accountdb");
	return true;
}
bool CRegisterAppTx::GetAddress(set<CKeyID> &vAddr, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {
	CKeyID keyId;
	if (!view.GetKeyId(regAcctId, keyId))
		return false;
	vAddr.insert(keyId);
	return true;
}
string CRegisterAppTx::ToString(CAccountViewCache &view) const {
	string str;
	CKeyID keyId;
	view.GetKeyId(regAcctId, keyId);
	str += strprintf("txType=%s, hash=%s, ver=%d, accountId=%s, keyid=%s, llFees=%ld, nValidHeight=%d\n",
	txTypeArray[nTxType], GetHash().ToString().c_str(), nVersion,boost::get<CRegID>(regAcctId).ToString(), keyId.GetHex(), llFees, nValidHeight);
	return str;
}
Object CRegisterAppTx::ToJSON(const CAccountViewCache &AccountView) const{
	Object result;
	CAccountViewCache view(AccountView);
    CKeyID keyid;
	result.push_back(Pair("hash", GetHash().GetHex()));
	result.push_back(Pair("txtype", txTypeArray[nTxType]));
	result.push_back(Pair("ver", nVersion));
	result.push_back(Pair("regid",  boost::get<CRegID>(regAcctId).ToString()));
	view.GetKeyId(regAcctId, keyid);
	result.push_back(Pair("addr", keyid.ToAddress()));
	result.push_back(Pair("script", "script_content"));
	result.push_back(Pair("fees", llFees));
	result.push_back(Pair("height", nValidHeight));
	return result;
}
bool CRegisterAppTx::CheckTransction(CValidationState &state, CAccountViewCache &view, CScriptDBViewCache &scriptDB) {

	if (regAcctId.type() != typeid(CRegID)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx regAcctId must be CRegID"), REJECT_INVALID,
				"regacctid-type-error");
	}

	if (!MoneyRange(llFees)) {
			return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx CheckTransction, tx fee out of range"), REJECT_INVALID,
					"fee-too-large");
	}

	uint64_t llFuel = ceil(script.size()/100) * GetFuelRate(scriptDB);
	if (llFuel < 1 * COIN) {
		llFuel = 1 * COIN;
	}

	if( llFees < llFuel) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx CheckTransction, register app tx fee too litter (actual:%lld vs need:%lld)", llFees, llFuel), REJECT_INVALID,
							"fee-too-litter");
	}

	CAccount acctInfo;
	if (!view.GetAccount(boost::get<CRegID>(regAcctId), acctInfo)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx CheckTransction, get account falied"), REJECT_INVALID, "bad-getaccount");
	}
	if (!acctInfo.IsRegister()) {
		return state.DoS(100, ERRORMSG("CheckTransaction(): CRegisterAppTx CheckTransction, account have not registed public key"), REJECT_INVALID,
				"bad-no-pubkey");
	}
	uint256 signhash = SignatureHash();
	if (!CheckSignScript(signhash, signature, acctInfo.PublicKey)) {
		return state.DoS(100, ERRORMSG("CheckTransaction() : CRegisterAppTx CheckTransction, CheckSignScript failed"), REJECT_INVALID,
				"bad-signscript-check");
	}
	return true;
}
uint256 CRegisterAppTx::GetHash() const
{
	return SignatureHash();
}
uint256 CRegisterAppTx::SignatureHash() const {
	CHashWriter ss(SER_GETHASH, 0);
	CID regAccId(regAcctId);
	ss << VARINT(nVersion) << nTxType << VARINT(nValidHeight) << regAccId << script << VARINT(llFees);
	return ss.GetHash();
}

string CAccountLog::ToString() const {
	string str("");
	str += strprintf("    Account log: keyId=%d llValues=%lld nHeight=%lld nCoinDay=%lld\n",
			keyID.GetHex(), llValues, nHeight, nCoinDay);
	return str;
}

string CTxUndo::ToString() const {
	vector<CAccountLog>::const_iterator iterLog = vAccountLog.begin();
	string strTxHash("txHash:");
	strTxHash += txHash.GetHex();
	strTxHash += "\n";
	string str("  list account Log:\n");
	for (; iterLog != vAccountLog.end(); ++iterLog) {
		str += iterLog->ToString();
	}
	strTxHash += str;
	vector<CScriptDBOperLog>::const_iterator iterDbLog = vScriptOperLog.begin();
	string strDbLog(" list script db Log:\n");
	for	(; iterDbLog !=  vScriptOperLog.end(); ++iterDbLog) {
		strDbLog += iterDbLog->ToString();
	}
	strTxHash += strDbLog;
	return strTxHash;
}
bool CTxUndo::GetAccountOperLog(const CKeyID &keyId, CAccountLog &accountLog) {
	vector<CAccountLog>::iterator iterLog = vAccountLog.begin();
	for (; iterLog != vAccountLog.end(); ++iterLog) {
		if (iterLog->keyID == keyId) {
			accountLog = *iterLog;
			return true;
		}
	}
	return false;
}

bool CAccount::UndoOperateAccount(const CAccountLog & accountLog) {
	LogPrint("undo_account", "after operate:%s\n", ToString());
	llValues = 	accountLog.llValues;
	nHeight = accountLog.nHeight;
	nCoinDay = accountLog.nCoinDay;
	LogPrint("undo_account", "before operate:%s\n", ToString().c_str());
	return true;
}
void CAccount::ClearAccPos(int nCurHeight) {
	UpDateCoinDay(nCurHeight);
	nCoinDay = 0;
}
uint64_t CAccount::GetAccountPos(int nCurHeight){
	UpDateCoinDay(nCurHeight);
	return nCoinDay;
}
bool CAccount::UpDateCoinDay(int nCurHeight) {
	if(nCurHeight < nHeight){
		return false;
	}
	else if(nCurHeight == nHeight){
		return true;
	}
	else{
		nCoinDay += llValues * ((int64_t)nCurHeight-(int64_t)nHeight);
		nHeight = nCurHeight;
		if(nCoinDay > GetMaxCoinDay(nCurHeight)) {
			nCoinDay = GetMaxCoinDay(nCurHeight);
		}
		return true;
	}
}
uint64_t CAccount::GetRawBalance() {
	return llValues;
}
Object CAccount::ToJosnObj() const
{
	Object obj;
	obj.push_back(Pair("Address",     keyID.ToAddress()));
	obj.push_back(Pair("KeyID",     keyID.ToString()));
	obj.push_back(Pair("RegID",     regID.ToString()));
	obj.push_back(Pair("PublicKey",  PublicKey.ToString()));
	obj.push_back(Pair("MinerPKey",  MinerPKey.ToString()));
	obj.push_back(Pair("Balance",     llValues));
	obj.push_back(Pair("CoinDays", nCoinDay/SysCfg().GetIntervalPos()/COIN));
	obj.push_back(Pair("UpdateHeight", nHeight));
	std::shared_ptr<CAccount> pNewAcct = GetNewInstance();
	pNewAcct->UpDateCoinDay(chainActive.Tip()->nHeight);
	obj.push_back(Pair("CurCoinDays", pNewAcct->nCoinDay/SysCfg().GetIntervalPos()/COIN));
	return obj;
}
string CAccount::ToString() const {
	string str;
	str += strprintf("regID=%s, keyID=%s, publicKey=%s, minerpubkey=%s, values=%ld updateHeight=%d coinDay=%lld\n",
	regID.ToString(), keyID.GetHex().c_str(), PublicKey.ToString().c_str(), MinerPKey.ToString().c_str(), llValues, nHeight, nCoinDay);
	return str;
}
bool CAccount::IsMoneyOverflow(uint64_t nAddMoney) {
	if (!MoneyRange(nAddMoney))
		return ERRORMSG("money:%lld too larger than MaxMoney");
	return true;
}

bool CAccount::OperateAccount(OperType type, const uint64_t &value, const int nCurHeight) {
	LogPrint("op_account", "before operate:%s\n", ToString());
	if (!IsMoneyOverflow(value))
		return false;

	if (UpDateCoinDay(nCurHeight) < 0) {
		LogPrint("INFO", "call UpDateCoinDay failed: cur height less than update height\n");
		return false;
	}

	if (keyID == uint160()) {
		return ERRORMSG("operate account's keyId is 0 error");
//		assert(0);
	}
	if (!value)
		return true;
	switch (type) {
	case ADD_FREE: {
		llValues += value;
		if (!IsMoneyOverflow(llValues))
			return false;
		break;
	}
	case MINUS_FREE: {
		if (value > llValues)
			return false;
		uint64_t remainCoinDay;
		if(nCurHeight<nBlockRemainCoinDayHeight)
		{
			remainCoinDay = nCoinDay - value / llValues * nCoinDay;
		}
		else
		{
			arith_uint256 nCoinDay256=(arith_uint256)nCoinDay;
			arith_uint256 llValues256=(arith_uint256)llValues;
			arith_uint256 value256=(arith_uint256)value;
			assert((llValues256 - value256) >= 0);
			arith_uint256 remainCoinDay256=(nCoinDay256*(llValues256 - value256)) / llValues256;
			remainCoinDay = remainCoinDay256.GetLow64();
			//LogPrint("CGP", "\n nHeight=%d\n remainCoinDay=%d\n nCoinDay=%d\n llValues=%d\n value=%d\n",nHeight,remainCoinDay,nCoinDay,llValues,value);//CGPADD FOR TEST
		}

		if (nCoinDay > llValues * SysCfg().GetIntervalPos()) {
			if (remainCoinDay < llValues * SysCfg().GetIntervalPos())
				remainCoinDay = llValues * SysCfg().GetIntervalPos();
		}
		nCoinDay = remainCoinDay;
		llValues -= value;
		break;
	}
	default:
		return ERRORMSG("operate account type error!");
//		assert(0);
	}
	LogPrint("op_account", "after operate:%s\n", ToString());
	return true;
}

max_stars_repo_name: koalajack/koalachain

max_issues_repo_name: koalajack/koalachain

max_forks_repo_name: koalajack/koalachain


text:
#ifndef GENERIC_SERVICE_HPP
#define GENERIC_SERVICE_HPP

#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <vector>
#include <iostream>

#include "io_context_pool.hpp"

class signal_handle
{
  public:
    signal_handle(io_context_pool &pool) : signal_(pool.get_io_context())
    {
        signal_.add(SIGINT);
        signal_.add(SIGTERM);
        signal_.async_wait([&pool](const boost::system::error_code &, int) { pool.stop(); });
    }

  private:
    boost::asio::signal_set signal_;
};

template <typename Session>
    class asio_generic_server final : private boost::noncopyable
{
    using shared_handler_t = std::shared_ptr<Session>;
    using tcp = boost::asio::ip::tcp;

  public:
    asio_generic_server(std::size_t num_pool, uint16_t port)
        : io_pool_(num_pool), acceptor_(io_pool_.get_io_context(), tcp::endpoint(tcp::v4(), port)), signal_(io_pool_)
    {
        do_accept();
    }
    void run() { io_pool_.run(); }

  private:
    void handle_connect(shared_handler_t handler, const boost::system::error_code &ec)
    {
        //std::cerr << ec.message() << "\n";
        if (!ec)
        {
            handler->start();
            do_accept();
        }
    }
    void do_accept()
    {
        auto handler = std::make_shared<Session>(io_pool_.get_io_context());
        acceptor_.async_accept(handler->socket(),
                              [this, handler](auto ec) { this->handle_connect(handler, ec); });
    }

  private:
    io_context_pool io_pool_;

    tcp::acceptor   acceptor_;
    signal_handle   signal_;
};

#endif // GENERIC_SERVICE_HPP

ext: hpp


text:
#ifndef RCLCPP_RCLCPP_SUBSCRIPTION_SUBSCRIPTION_HPP_
#define RCLCPP_RCLCPP_SUBSCRIPTION_SUBSCRIPTION_HPP_
#include <functional>
#include <iostream>
#include <memory>

#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <ccpp_dds_dcps.h>
#include <dds_dcps.h>

#include <genidlcpp/resolver.h>

namespace rclcpp
{

// Forward declare Node class for friendship with Publisher Interface
namespace node {class Node;}

namespace subscription
{

class SubscriptionInterface
{
public:
    typedef std::shared_ptr<SubscriptionInterface> Ptr;
    virtual bool spin_once() = 0;
    virtual bool spin_some() = 0;
    virtual DDS::StatusCondition * get_status_condition() = 0;
};

template <typename ROSMsgType>
class Subscription : public SubscriptionInterface
{
public:
    typedef std::function<void(typename ROSMsgType::ConstPtr)> CallbackType;
    typedef std::shared_ptr<Subscription<ROSMsgType> > Ptr;
private:
    typedef dds_impl::DDSTypeResolver<ROSMsgType> r;
    friend class node::Node;
    Subscription(const std::string &topic_name, typename r::DDSMsgDataReaderType_var data_reader, CallbackType cb)
    : topic_name_(topic_name), data_reader_(data_reader), cb_(cb)
    {
        this->condition_ = this->data_reader_->get_statuscondition();
        this->condition_->set_enabled_statuses(DDS::DATA_AVAILABLE_STATUS);
    }

    bool spin_(DDS::ULong read_length)
    {
        typename r::DDSMsgSeqType_var dds_msg_seq = new typename r::DDSMsgSeqType();
        DDS::SampleInfoSeq_var sample_info_seq = new DDS::SampleInfoSeq();
        this->data_reader_->take(
            dds_msg_seq,
            sample_info_seq,
            read_length,
            DDS::ANY_SAMPLE_STATE,
            DDS::ANY_VIEW_STATE,
            DDS::ALIVE_INSTANCE_STATE
        );

        bool result = true;
        if (dds_msg_seq->length() == 0)
        {
            result = false;
        }

        for (DDS::ULong i = 0; i < dds_msg_seq->length(); i++)
        {
            typename ROSMsgType::Ptr ros_msg(new ROSMsgType());
            dds_impl::DDSTypeResolver<ROSMsgType>::convert_dds_message_to_ros(dds_msg_seq[i], (*ros_msg.get()));
            try {
                this->cb_(ros_msg);
            } catch (const std::exception& e) {
                std::cerr << "Error handling callback for subscription to topic '" << this->topic_name_ << "':"
                          << std::endl << e.what() << std::endl;
            }
        }
        this->data_reader_->return_loan(dds_msg_seq, sample_info_seq);
        return result;
   }
public:
    ~Subscription() {}

    DDS::StatusCondition * get_status_condition()
    {
        return this->condition_;
    }

    bool spin_once()
    {
        return this->spin_(1);
    }

    bool spin_some()
    {
        return this->spin_(DDS::LENGTH_UNLIMITED);
    }

private:
    typename r::DDSMsgDataReaderType_var data_reader_;
    CallbackType cb_;
    std::string topic_name_;
    DDS::StatusCondition * condition_;
};

}

}

#endif /* RCLCPP_RCLCPP_SUBSCRIPTION_SUBSCRIPTION_HPP_ */


text:
// Copyright 2019 The Bitcoin SV Developers
// Based on vmtouch - https://github.com/hoytech/vmtouch
//
/***********************************************************************
vmtouch - the Virtual Memory Toucher
Portable file system cache diagnostics and control
by Doug Hoyte (doug@hcsw.org)
************************************************************************

Copyright (c) 2009-2017 Doug Hoyte and contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/

#ifndef WIN32

#include "vmtouch.h"

#include <unistd.h>
#include <stdio.h>

#include <exception>

#include <sys/time.h>
#include <sys/resource.h>
#include <sys/mman.h>

#include <signal.h>

#include "logging.h"

#if defined(__linux__)
    #include <sys/ioctl.h>
    #include <sys/mount.h>
#endif

#include <libgen.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>

#include "fs.h"
#include "cfile_util.h"

#include <stdarg.h>

#include <boost/noncopyable.hpp>
#include <functional>
#include <boost/thread/thread.hpp> // boost::thread::interrupt

// Takes ownership of result of opendir() and closes it in destructor.
class CAutoCloseDir : public boost::noncopyable {
  DIR * dir;
  std::function<void(const std::string& message)> warning;
public:

  CAutoCloseDir(DIR* dir, std::function<void(const std::string& message)> warning) : dir(dir), warning(warning)
  {
  }

  ~CAutoCloseDir()
  {
    if (closedir(dir))
    {
      char* msg = strerror(errno);
      warning(std::string("unable to closedir. ") +  std::string(msg));
    }
  }
};

// Takes ownership of memory mapped region and unmaps it in destructor unless Release() is called
class CAutoMunmap : public boost::noncopyable {
  void* mem = nullptr;
  uint64_t len_of_range = 0;
  std::function<void(const std::string& message)> warning;
public:
  CAutoMunmap(void *mem,uint64_t len_of_range, std::function<void(const std::string& message)> warning)
   :  mem(mem), len_of_range(len_of_range), warning(warning)
  {  }

  void Release()
  {
    mem = nullptr;
  }

  ~CAutoMunmap()
  {
    if (mem && munmap(mem, len_of_range) != 0) {
      char* msg = strerror(errno);
      warning(std::string("unable to munmap file. ") +  std::string(msg));
    }
  }

};

VMTouch::VMTouch() : pagesize(sysconf(_SC_PAGESIZE))
{
    curr_crawl_depth = 0;
}

VMTouch::~VMTouch()
{   }

static void fatal(const char *fmt, ...) {
    va_list ap;
    char buf[4096];

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    throw std::runtime_error(buf);
}
void VMTouch::warning(const char *fmt, ...) {
    va_list ap;
    char buf[4096];

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    warnings.emplace_back(buf);

}
int VMTouch::aligned_p(void* p)
{
    return 0 == ((long)p & (pagesize - 1));
}

int64_t VMTouch::bytes2pages(uint64_t bytes)
{
    return (bytes + pagesize - 1) / pagesize;
}

int VMTouch::is_mincore_page_resident(char p)
{
    return p & 0x1;
}

void VMTouch::increment_nofile_rlimit()
{
    struct rlimit r;

    if (getrlimit(RLIMIT_NOFILE, &r))
      fatal("increment_nofile_rlimit: getrlimit (%s)", strerror(errno));

    r.rlim_cur = r.rlim_max + 1;
    r.rlim_max = r.rlim_max + 1;

    if (setrlimit(RLIMIT_NOFILE, &r)) {
        if (errno == EPERM) {
            if (getuid() == 0 || geteuid() == 0) {
              fatal("system open file limit reached");
            }
            fatal("open file limit reached and unable to increase limit. retry as root");
        }
        fatal("increment_nofile_rlimit: setrlimit (%s)", strerror(errno));

    }
}
void VMTouch::vmtouch_file(const std::string& strPath)
{
    int fd = -1;
    void* mem = nullptr;
    struct stat sb;
    int64_t len_of_file=0;
    uint64_t len_of_range=0;
    int64_t pages_in_range;
    int i;
    int res;
    int open_flags;
    int max_len = 0;
    int offset = 0;

    retry_open:

    open_flags = O_RDONLY;

  #if defined(O_NOATIME)
    open_flags |= O_NOATIME;
  #endif

    fd = open(strPath.c_str(), open_flags, 0);

  #if defined(O_NOATIME)
    if (fd == -1 && errno == EPERM) {
      open_flags &= ~O_NOATIME;
      fd = open(strPath.c_str(), open_flags, 0);
    }
  #endif

    if (fd == -1) {
      if (errno == ENFILE || errno == EMFILE) {
        increment_nofile_rlimit();
        goto retry_open;
      }

      warning("unable to open %s (%s), skipping", strPath.c_str(), strerror(errno));
      return;
    }

    // File was sucesfully open. Make sure that it is closed.
    UniqueFileDescriptor file {fd};
    res = fstat(fd, &sb);

    if (res) {
      warning("unable to fstat %s (%s), skipping", strPath.c_str(), strerror(errno));
      return;
    }

    if (S_ISBLK(sb.st_mode)) {
  #if defined(__linux__)
      if (ioctl(fd, BLKGETSIZE64, &len_of_file)) {
        warning("unable to ioctl %s (%s), skipping", strPath.c_str(), strerror(errno));
        return;
      }
  #else
        fatal("discovering size of block devices not (yet?) supported on this platform");
  #endif
    } else {
      len_of_file = sb.st_size;
    }

    if (len_of_file == 0) {
        return;
    }

    if (len_of_file > o_max_file_size) {
      warning("file %s too large, skipping", strPath.c_str());
      return;
    }

    if (max_len > 0 && (offset + max_len) < len_of_file) {
      len_of_range = max_len;
    } else if (offset >= len_of_file) {
      warning("file %s smaller than offset, skipping", strPath.c_str());
      return;
    } else {
      len_of_range = len_of_file - offset;
    }

    auto warning_callback = [this, &strPath](const std::string& message) {
        this->warning("%s %s", message.c_str(), strPath.c_str());
    };

    mem = mmap(nullptr, len_of_range, PROT_READ, MAP_SHARED, fd, offset);

    if (mem == MAP_FAILED) {
        warning("unable to mmap file %s (%s), skipping", strPath.c_str(), strerror(errno));
        return;
    }

    // Memory was mapped. Unmap it automatically unless lock was sucesful:
    CAutoMunmap mapped_memory(mem, len_of_range, warning_callback);

    if (aligned_p(mem) == 0) {
        fatal("mmap(%s) wasn't page aligned", strPath.c_str());
    }

    pages_in_range = bytes2pages(len_of_range);

    total_pages += pages_in_range;

    if (o_evict) {
      //if (o_verbose) printf("Evicting %s\n", path);

  #if defined(__linux__) || defined(__hpux)
      if (posix_fadvise(fd, offset, len_of_range, POSIX_FADV_DONTNEED)) {
          warning("unable to posix_fadvise file %s (%s)", strPath.c_str(), strerror(errno));
      }

  #elif defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__)
      if (msync(mem, len_of_range, MS_INVALIDATE)) {
          warning("unable to msync invalidate file %s (%s)", strPath.c_str(), strerror(errno));
      }

  #else
      fatal("cache eviction not (yet?) supported on this platform");
  #endif
    } else {
      //double last_chart_print_time=0.0, temp_time;
      #ifdef __APPLE__
          std::vector<char> mincore_array(pages_in_range);
      #else
          std::vector<unsigned char> mincore_array(pages_in_range);
      #endif

      // 3rd arg to mincore is char* on BSD and unsigned char* on linux
      if (mincore(mem, len_of_range, mincore_array.data()) != 0) {
          fatal("mincore %s (%s)", strPath.c_str(), strerror(errno));
      }
      for (i=0; i<pages_in_range; i++) {
        if (is_mincore_page_resident(mincore_array[i])) {
          total_pages_in_core++;
        }
      }

      /*if (o_verbose) {
        printf("%s\n", path);
        last_chart_print_time = gettimeofday_as_double();
        print_page_residency_chart(stdout, mincore_array, pages_in_range);
      }*/

      if (o_touch) {
        for (i=0; i<pages_in_range; i++) {
          junk_counter += ((char*)mem)[i*pagesize];
          mincore_array[i] = 1;

          /*if (o_verbose) {
            temp_time = gettimeofday_as_double();

            if (temp_time > (last_chart_print_time+CHART_UPDATE_INTERVAL)) {
              last_chart_print_time = temp_time;
              print_page_residency_chart(stdout, mincore_array, pages_in_range);
            }
          }*/
        }
      }

      /*if (o_verbose) {
        print_page_residency_chart(stdout, mincore_array, pages_in_range);
        printf("\n");
      }*/

    }

    if (o_lock) {
      if (mlock(mem, len_of_range) != 0) {
          fatal("mlock: %s (%s)", strPath.c_str(), strerror(errno));
      }
      // Release ownership, to keep apges locked
      mapped_memory.Release();
    }

}

void VMTouch::add_object(const struct stat& st)
{
    seen_inodes.emplace( dev_and_inode { st.st_dev, st.st_ino});
}

bool VMTouch::is_ignored(const std::string& path)
{
    if (ignoreList.empty()) {
        return false;
    }

    // basename() modifies input buffer so make a copy.
    // It might return pointer into path_copy or to some static allocated moemory
    std::string path_copy(path.c_str());

    char *filename = basename(path_copy.data());

    for(auto& ignoreItem : ignoreList) {
        if (fnmatch(ignoreItem.c_str(), filename, 0) == 0) {
            return true;
        }
    }

    return false;
}

bool VMTouch::is_filename_filtered(const std::string& path)
{
    if (filenameFilterList.empty()) {
        return true;
    }

    // basename() modifies input buffer so make a copy.
    // It might return pointer into path_copy or to some static allocated moemory
    std::string path_copy(path.c_str());

    char *filename = basename(path_copy.data());

    for(auto& filterItem : filenameFilterList) {
        if (fnmatch(filterItem.c_str(), filename, 0) == 0) {
            return true;
        }
    }
    return false;
}

// returns true if st HAS been added before
bool VMTouch::find_object(const struct stat& st)
{
    struct dev_and_inode obj {st.st_dev, st.st_ino};
    return seen_inodes.find(obj) != seen_inodes.end();
}

void VMTouch::vmtouch_crawl(std::string strPath)
{
    struct stat sb;
    DIR *dirp;
    struct dirent *de;
    std::string npath;
    int res;
    int tp_path_len = strPath.length();
    int i;

    if (strPath.empty())
    {
        throw std::invalid_argument("Invalid argument - path must not be empty");
    }

    if (strPath[tp_path_len-1] == '/' && tp_path_len > 1)
        strPath[tp_path_len-1] = '\0'; // prevent ugly double slashes when printing path names

    if (is_ignored(strPath)) {
      return;
    }

    res = o_followsymlinks ? stat(strPath.c_str(), &sb) : lstat(strPath.c_str(), &sb);

    if (res) {
      warning("unable to stat %s (%s)", strPath.c_str(), strerror(errno));
      return;
    } else {
      if (S_ISLNK(sb.st_mode)) {
        warning("not following symbolic link %s", strPath.c_str());
        return;
      }

      if (o_singlefilesystem) {
        if (!orig_device_inited) {
          orig_device = sb.st_dev;
          orig_device_inited = true;
        } else {
          if (sb.st_dev != orig_device) {
            warning("not recursing into separate filesystem %s", strPath.c_str());
            return;
          }
        }
      }

      if (!o_ignorehardlinkeduplictes && sb.st_nlink > 1) {
        /*
         * For files with more than one link to it, ignore it if we already know
         * inode.  Without this check files copied as hardlinks (cp -al) are
         * counted twice (which may lead to a cache usage of more than 100% of
         * RAM).
         */
        if (find_object(sb)) {
          // we already saw the device and inode referenced by this file
          return;
        } else {
          add_object(sb);
        }
      }

      if (S_ISDIR(sb.st_mode)) {
        for (i=0; i<curr_crawl_depth; i++) {
          if (crawl_inodes[i] == sb.st_ino) {
            warning("symbolic link loop detected: %s", strPath.c_str());
            return;
          }
        }

        if (curr_crawl_depth == MAX_CRAWL_DEPTH) {
          fatal("maximum directory crawl depth reached: %s", strPath.c_str());
        }

        total_dirs++;

        crawl_inodes[curr_crawl_depth] = sb.st_ino;

        retry_opendir:

        dirp = opendir(strPath.c_str());

        if (dirp == NULL) {
          if (errno == ENFILE || errno == EMFILE) {
            increment_nofile_rlimit();
            goto retry_opendir;
          }

          warning("unable to opendir %s (%s), skipping", strPath.c_str(), strerror(errno));
          return;
        }

        auto warning_callback = [this, &strPath](const std::string& message) {
            this->warning("%s %s", message.c_str(), strPath.c_str());
        };

        CAutoCloseDir dir(dirp, warning_callback);
        while((de = readdir(dirp)) != NULL) {

          boost::this_thread::interruption_point();

          if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;

          npath = strPath + "/" + de->d_name;

          curr_crawl_depth++;
          vmtouch_crawl(npath);
          curr_crawl_depth--;
        }

      } else if (S_ISLNK(sb.st_mode)) {
        warning("not following symbolic link %s", strPath.c_str());
        return;
      } else if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) {
        if (is_filename_filtered(strPath.c_str())) {
          total_files++;
          vmtouch_file(strPath);
        }
      } else {
        warning("skipping non-regular file: %s\n", strPath.c_str());
      }
    }
}

void VMTouch::vmtouch_touch(const std::string& strPath)
{
    o_touch = true;
    o_evict = false;
    vmtouch_crawl(strPath);
}

double VMTouch::vmtouch_check(const std::string& strPath)
{
    o_touch = false;
    o_evict = false;
    vmtouch_crawl(strPath);
    return getPagesInCorePercent();
}

double VMTouch::getPagesInCorePercent()
{
  if (total_pages == 0)
  {
    // Avoid division by zero. If there are no pages to load, we assume, that everything is loaded
    return 100;
  }

  return 100.0*total_pages_in_core/total_pages;
}

#endif

ext: cpp

max_stars_repo_name: AustEcon/bitcoin-sv

max_issues_repo_name: wjxee/bitcoin-sv

max_forks_repo_name: wjxee/bitcoin-sv


text:
//======================================================================
/*! \file Lane.hpp
 *
 * \copydoc Copyright
 * \author Stefan Kaufmann (stk)
 * \date Oct 9, 2014
 * \brief Lane which has a list of LaneSegments
 *///-------------------------------------------------------------------

#ifndef IBEOSDK_LANE_HPP
#define IBEOSDK_LANE_HPP

//======================================================================

#include <ibeosdk/misc/WinCompatibility.hpp>

#include <ibeosdk/inttypes.hpp>
#include <ibeosdk/datablocks/snippets/Snippet.hpp>
#include <ibeosdk/LaneType.hpp>

#include <boost/unordered_map.hpp>

#include <ibeosdk/datablocks/snippets/LaneSegment.hpp>

//======================================================================

namespace ibeosdk{
namespace lanes{

//======================================================================

class CarriageWaySegment;
class Lane;

typedef boost::shared_ptr<CarriageWaySegment> CarriageWaySegmentPtr;
typedef boost::shared_ptr<const CarriageWaySegment> CarriageWaySegmentConstPtr;
typedef boost::shared_ptr<Lane> LanePtr;
typedef boost::shared_ptr<const Lane> LaneConstPtr;

//======================================================================
/*!\brief A Lane represents a Lane within a \ref CarriageWaySegment
 *
 * Each Lane has a unique id within the parent \ref CarriageWaySegment
 *
 * A Lane holds a list of LaneSegments as well as pointers to preceeding,
 * following and neighbouring Lanes.
 *
 * The segmentation of a whole road is as following:
 *
 * \ref CarriageWay \htmlonly→\endhtmlonly
 * \ref CarriageWaySegment \htmlonly→\endhtmlonly
 * \ref Lane \htmlonly→\endhtmlonly
 * \ref LaneSegment
 *
 * The connection is handled using smart pointers. Therefore it is not possible
 * to create an instance of this class, but calling \ref create will return
 * a shared pointer to a new Lane.
 *
 * \sa CarriageWay \sa CarriageWaySegment \sa LaneSegment
 *///-------------------------------------------------------------------
class Lane : public ibeosdk::Snippet {
private: // constructors
	//========================================
	/*! \brief private constructor called by \ref create() \sa create */
	Lane();

	/*! \brief private constructor called by \ref create \sa create */
	Lane(CarriageWaySegmentPtr parent);

	/*! \brief private constructor called by \ref create \sa create */
	Lane(const UINT8& id,
	     const UINT64 laneId,
	     const LaneType& type,
	     CarriageWaySegmentPtr parent,
	     const UINT8& nextLaneId,
	     const UINT8& previousLaneId,
	     const UINT8& leftLaneId,
	     const UINT8& rightLaneId);

public:
	/*! \brief Default constructor
	 * Initializes all members to 0
	 * \return A shared pointer to the created Lane
	 */
	static LanePtr create();

	/*! \brief Constructor
	 * \param[in] parent A pointer to the parent CarriageWaySegment
	 * \return A shared pointer to the created Lane
	 */
	static LanePtr create(CarriageWaySegmentPtr parent);

	/*! \brief Constructor
	 * \param[in] id The unique id of this Lane within the parent CarriageWaySegment
	 * \param[in] laneId The unique id of the Lane within the parent CarriageWay
	 * \param[in] type The \ref LaneType of this Lane
	 * \param[in] parent A pointer to the parent CarriageWaySegment
	 * \param[in] nextLaneId The id of the following Lane (0 if there is none)
	 * \param[in] previousLaneId The id of the preceeding Lane ( 0 if there is none)
	 * \param[in] leftLaneId The id of the left neighbouring Lane (0 if there is none)
	 * \param[in] rightLaneId The id of the right neighbouring Lane (0 if there is none)
	 */
	static LanePtr create(const UINT8& id,
	                      const UINT64 laneId,
	                      const LaneType& type,
	                      CarriageWaySegmentPtr parent,
	                      const UINT8& nextLaneId,
	                      const UINT8& previousLaneId,
	                      const UINT8& leftLaneId,
	                      const UINT8& rightLaneId);

	static LanePtr copy(const LanePtr& other);

public: // setter & getter
	//========================================
	/*! \brief Returns the unique id for the Lane within the \ref CarriageWaySegment */
	UINT8 getId() const;

	/*! \brief Sets the unique id for the Lane within the \ref CarriageWaySegment */
	void setId(const UINT8& id);

	/*! \brief Returns the unique id of the Lane within the parent \ref CarriageWay (0 if there is none) */
	UINT64 getLaneId() const;

	/*! \brief Sets the unique id of the Lane within the parent \ref CarriageWay */
	void setLaneId(const UINT64& id);

	/*! \brief Returns the pointer to the parent \ref CarriageWaySegment */
	const CarriageWaySegmentPtr getParent() const;

	/*! \brief Sets the pointer to the parent \ref CarriageWaySegment */
	void setParent(const CarriageWaySegmentPtr& parent);

	/*! \brief Return the pointer to the following Lane (0 if there is none) */
	const LanePtr getNext() const;

	/*! \brief Sets the pointer to the next Lane */
	void setNext(const LanePtr& next);

	/*! \brief Return the pointer to the preceeding Lane (0 if there is none) */
	const LanePtr getPrevious() const;

	/*! \brief Sets the pointer to the previous Lane */
	void setPrevious(const LanePtr& previous);

	/*! \brief Return the pointer to the left neighbouring Lane (0 if there is none) */
	const LanePtr getLeft() const;

	/*! \brief Sets the pointer to the left Lane */
	void setLeft(const LanePtr& left);

	/*! \brief Return the pointer to the right neighbouring Lane (0 if there is none) */
	const LanePtr getRight() const;

	/*! \brief Sets the pointer to the right Lane */
	void setRight(const LanePtr& right);

	/*! \brief Returns the type of the Lane */
	LaneType getType() const;

	void setType(const LaneType type);

	UINT8 getNextLaneId() const;
	void setNextLaneId(const UINT8 nextId);

	UINT8 getPrevLaneId() const;
	void setPrevLaneId(const UINT8 prevId);

	UINT8 getLeftLaneId() const;
	void setLeftLaneId(const UINT8 leftId);

	UINT8 getRightLaneId() const;
	void setRightLaneId(const UINT8 rightId);

	void updateConnectionIDs(const LanePtr& reference, const bool override = true);

	/*! \brief Returns a pointer to the map with all child LaneSegments */
	const LaneSegmentMap& getSegments() const;
	LaneSegmentMap& getSegments();

	/*! \brief Sets all child LaneSegments to the given ones */
	void setSegments(const LaneSegmentMap& segments);

	/*! \brief Returns a bounding rectangle of the way which is currently not the
	 * minimal one, but the one aligned to the north vector
	 */
	BoundingRectangle getBoundingBox() const;
	UINT64 getNextFreeKey() const;

	//========================================

	/*! \brief Inserts a single LaneSegment to this lane */
	bool insert(LaneSegmentPtr segment);

	/*! \brief Returns true if the Lane has a following Lane, false otherwise */
	bool hasNext() const;

	/*! \brief Returns true if the Lane has a preceeding Lane, false otherwise */
	bool hasPrevious() const;

	/*! \brief Returns true if the Lane has a left neighbouring Lane, false otherwise */
	bool hasLeft() const;

	/*! \brief Returns true if the Lane has a right neighbouring Lane, false otherwise */
	bool hasRight() const;

	void cleanIds();

public:
	//========================================
	virtual std::streamsize getSerializedSize() const;
	virtual bool deserialize(std::istream& is);
	virtual bool serialize(std::ostream& os) const;

	//========================================

private:
	void init();

public: // public static attributes
	//========================================
	/*! \brief The version of this implementation */
	static std::string const VERSION;

private: // private attributes
	//========================================
	// Members
	UINT8 m_id;
	UINT64 m_laneId;

	LaneType m_type;
	boost::weak_ptr<CarriageWaySegment> m_parent;

	UINT8 m_nextLaneId;
	UINT8 m_prevLaneId;
	UINT8 m_leftLaneId;
	UINT8 m_rightLaneId;

	boost::weak_ptr<Lane> m_nextLane;
	boost::weak_ptr<Lane> m_prevLane;
	boost::weak_ptr<Lane> m_leftLane;
	boost::weak_ptr<Lane> m_rightLane;
	LaneSegmentMap m_segments;

	BoundingRectangle m_boundingBox;

	friend class CarriageWay;
}; // class Lane

//======================================================================

typedef boost::unordered_map<UINT8, LanePtr> LaneMap;
typedef LaneMap::value_type LaneMapEntry;

//======================================================================

} // namespace lanes
} // namespace ibeo

//======================================================================

#endif // IBEOSDK_LANE_HPP

//======================================================================


text:
/******************************************************************
 *
 * uEcho for C
 *
 * Copyright (C) Satoshi Konno 2015
 *
 * This is licensed under BSD-style license, see file COPYING.
 *
 ******************************************************************/

#include <boost/test/unit_test.hpp>

#include <stdlib.h>

#include <uecho/util/bytes.h>

BOOST_AUTO_TEST_CASE(Bytes)
{
  byte* ibytes;
  int n;

  for (n = 0; n <= 0xFF; n++) {
    ibytes = uecho_bytes_fromint(n, 1);
    BOOST_CHECK_EQUAL(uecho_bytes_toint(ibytes, 1), n);
    free(ibytes);
  }

  for (n = 0; n <= 0xFFFF; n += (0xFFFF / 0xFF)) {
    ibytes = uecho_bytes_fromint(n, 2);
    BOOST_CHECK_EQUAL(uecho_bytes_toint(ibytes, 2), n);
    free(ibytes);
  }

  for (n = 0; n <= 0xFFFFFF; n += (0xFFFFFF / 0xFFFF)) {
    ibytes = uecho_bytes_fromint(n, 3);
    BOOST_CHECK_EQUAL(uecho_bytes_toint(ibytes, 3), n);
    free(ibytes);
  }
}


text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include "consensus/grandpa/impl/environment_impl.hpp"

#include <boost/optional/optional_io.hpp>
#include <utility>

#include "consensus/grandpa/justification_observer.hpp"
#include "scale/scale.hpp"

namespace kagome::consensus::grandpa {

  using primitives::BlockHash;
  using primitives::BlockNumber;
  using primitives::Justification;

  EnvironmentImpl::EnvironmentImpl(
      std::shared_ptr<blockchain::BlockTree> block_tree,
      std::shared_ptr<blockchain::BlockHeaderRepository> header_repository,
      std::shared_ptr<Gossiper> gossiper)
      : block_tree_{std::move(block_tree)},
        header_repository_{std::move(header_repository)},
        gossiper_{std::move(gossiper)},
        logger_{common::createLogger("Grandpa environment:")} {
    BOOST_ASSERT(block_tree_ != nullptr);
    BOOST_ASSERT(header_repository_ != nullptr);
    BOOST_ASSERT(gossiper_ != nullptr);
  }

  outcome::result<std::vector<BlockHash>> EnvironmentImpl::getAncestry(
      const BlockHash &base, const BlockHash &block) const {
    // if base equal to block, then return list with single block
    if (base == block) {
      return std::vector<BlockHash>{base};
    }

    OUTCOME_TRY(chain, block_tree_->getChainByBlocks(base, block));
    std::reverse(chain.begin(), chain.end());
    return std::move(chain);
  }

  bool EnvironmentImpl::hasAncestry(const BlockHash &base,
                                    const BlockHash &block) const {
    return base == block || block_tree_->hasDirectChain(base, block);
  }

  outcome::result<BlockInfo> EnvironmentImpl::bestChainContaining(
      const BlockHash &base) const {
    logger_->debug("Finding best chain containing block {}", base.toHex());
    OUTCOME_TRY(best_info, block_tree_->getBestContaining(base, boost::none));
    auto best_hash = best_info.block_hash;

    auto target = best_info.block_number;

    OUTCOME_TRY(best_header, header_repository_->getBlockHeader(best_hash));

    // walk backwards until we find the target block
    while (true) {
      if (best_header.number == target) {
        logger_->debug("found best chain: number {}, hash {}",
                       best_header.number,
                       best_hash.toHex());
        return BlockInfo{primitives::BlockNumber{best_header.number},
                         best_hash};
      }
      best_hash = best_header.parent_hash;
      OUTCOME_TRY(new_best_header,
                  header_repository_->getBlockHeader(best_hash));
      best_header = new_best_header;
    }
  }

  outcome::result<void> EnvironmentImpl::onCatchUpRequested(
      const libp2p::peer::PeerId &peer_id,
      MembershipCounter set_id,
      RoundNumber round_number) {
    network::CatchUpRequest message{.round_number = round_number,
                                    .voter_set_id = set_id};
    gossiper_->catchUpRequest(peer_id, message);
    logger_->debug("Catch-Up-Request sent from round #{}", round_number);
    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::onCatchUpResponsed(
      const libp2p::peer::PeerId &peer_id,
      MembershipCounter set_id,
      RoundNumber round_number,
      GrandpaJustification prevote_justification,
      GrandpaJustification precommit_justification,
      BlockInfo best_final_candidate) {
    network::CatchUpResponse message{
        .voter_set_id = set_id,
        .round_number = round_number,
        .prevote_justification = std::move(prevote_justification),
        .precommit_justification = std::move(precommit_justification),
        .best_final_candidate = best_final_candidate};
    gossiper_->catchUpResponse(peer_id, message);
    logger_->debug("Catch-Up-Response sent upto round {}", round_number);
    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::onProposed(
      RoundNumber round,
      MembershipCounter set_id,
      const SignedMessage &propose) {
    BOOST_ASSERT(propose.is<PrimaryPropose>());
    network::GrandpaVoteMessage message{
        {.round_number = round, .counter = set_id, .vote = propose}};
    gossiper_->vote(message);
    logger_->debug("Round #{}: Proposed block #{} with hash {}",
                   round,
                   propose.block_number(),
                   propose.block_hash().toHex());
    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::onPrevoted(
      RoundNumber round,
      MembershipCounter set_id,
      const SignedMessage &prevote) {
    BOOST_ASSERT(prevote.is<Prevote>());
    network::GrandpaVoteMessage message{
        {.round_number = round, .counter = set_id, .vote = prevote}};
    gossiper_->vote(message);
    logger_->debug("Round #{}: Prevoted block #{} with hash {}",
                   round,
                   prevote.block_number(),
                   prevote.block_hash().toHex());
    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::onPrecommitted(
      RoundNumber round,
      MembershipCounter set_id,
      const SignedMessage &precommit) {
    BOOST_ASSERT(precommit.is<Precommit>());
    network::GrandpaVoteMessage message{
        {.round_number = round, .counter = set_id, .vote = precommit}};
    gossiper_->vote(message);
    logger_->debug("Round #{}: Precommitted block #{} with hash {}",
                   round,
                   precommit.block_number(),
                   precommit.block_hash().toHex());
    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::onCommitted(
      RoundNumber round,
      const BlockInfo &vote,
      const GrandpaJustification &justification) {
    logger_->debug("Round #{}: Committed block #{} with hash {}",
                   round,
                   vote.block_number,
                   vote.block_hash.toHex());
    network::GrandpaPreCommit message{
        {.round_number = round, .vote = vote, .justification = justification}};
    gossiper_->finalize(message);
    return outcome::success();
  }

  void EnvironmentImpl::doOnCompleted(
      const CompleteHandler &on_completed_slot) {
    on_completed_.disconnect_all_slots();
    on_completed_.connect(on_completed_slot);
  }

  void EnvironmentImpl::onCompleted(
      outcome::result<MovableRoundState> round_state) {
    BOOST_ASSERT_MSG(
        not on_completed_.empty(),
        "Completed signal in environment cannot be empty when it is invoked");
    on_completed_(round_state);
  }

  outcome::result<void> EnvironmentImpl::applyJustification(
      const BlockInfo &block_info,
      const primitives::Justification &raw_justification) {
    auto justification_observer = justification_observer_.lock();
    BOOST_ASSERT(justification_observer);

    OUTCOME_TRY(
        justification,
        scale::decode<grandpa::GrandpaJustification>(raw_justification.data));

    OUTCOME_TRY(
        justification_observer->applyJustification(block_info, justification));

    return outcome::success();
  }

  outcome::result<void> EnvironmentImpl::finalize(
      const primitives::BlockHash &block_hash,
      const GrandpaJustification &grandpa_jusitification) {
    primitives::Justification justification;
    justification.data.put(scale::encode(grandpa_jusitification).value());
    return block_tree_->finalize(block_hash, justification);
  }

  outcome::result<GrandpaJustification> EnvironmentImpl::getJustification(
      const BlockHash &block_hash) {
    OUTCOME_TRY(encoded_justification,
                block_tree_->getBlockJustification(block_hash));

    OUTCOME_TRY(
        grandpa_jusitification,
        scale::decode<GrandpaJustification>(encoded_justification.data));

    return outcome::success(std::move(grandpa_jusitification));
  }

}  // namespace kagome::consensus::grandpa

max_stars_repo_name: Harrm/kagome

max_issues_repo_name: Harrm/kagome

max_forks_repo_name: Harrm/kagome


text:
#define BOOST_TEST_MODULE utility
#include <boost/test/included/unit_test.hpp>
#include <fstream>
#include <iostream>
#include <string>

#include "../src/utility.hpp"

BOOST_AUTO_TEST_SUITE(test_utility_sute)

BOOST_AUTO_TEST_CASE(test_correct_clamp) {
    BOOST_CHECK_EQUAL(clamp(1.1), 1.0);
    BOOST_CHECK_EQUAL(clamp(-0.1), 0.0);
    BOOST_CHECK_EQUAL(clamp(0.5), 0.5);
}

BOOST_AUTO_TEST_CASE(test_correct_to_int) {
    BOOST_CHECK_EQUAL(to_int(0.0), 0);
    BOOST_CHECK_EQUAL(to_int(1.0), 255);

    BOOST_CHECK_EQUAL(to_int(-0.1), 0);
    BOOST_CHECK_EQUAL(to_int(1.1), 255);
}

BOOST_AUTO_TEST_CASE(test_correct_linspace) {
    double start = 123, end = 456;
    int n = 50;

    auto result = linspace(start, end, n);
    BOOST_CHECK_EQUAL(result.size(), n);
    BOOST_CHECK_EQUAL(result[0], start);
    BOOST_CHECK_EQUAL(result[n - 1], end);

    start = 5;
    end = 10;
    n = 5;
    result = linspace(start, end, n, false);
    BOOST_CHECK_EQUAL(result.size(), n);
    BOOST_CHECK_EQUAL(result[0], start);
    BOOST_CHECK_EQUAL(result[n - 1], 9.0);
}

BOOST_AUTO_TEST_CASE(test_correct_save_and_load_ppm_file) {
    // save ppm file
    std::string filename = "test_image.ppm";
    int width_res = 4, height_res = 3;
    Color c = Color(1.0, 1.0, 1.0);
    Image image(width_res, height_res);

    for (int i = 0; i < image.height_res; i++) {
        for (int j = 0; j < image.width_res; j++) {
            image.set_color(c, i, j);
        }
    }
    save_ppm_file(filename, image);

    // load ppm file
    Image load_image = load_ascii_ppm_file(filename);

    BOOST_CHECK_EQUAL(load_image.width_res, width_res);
    BOOST_CHECK_EQUAL(load_image.height_res, height_res);
    for (int i = 0; i < load_image.height_res; i++) {
        for (int j = 0; j < load_image.width_res; j++) {
            BOOST_CHECK(load_image.get_color(i, j) == c);
        }
    }
}

BOOST_AUTO_TEST_CASE(test_correct_strip) {
    std::string s(" abc,def");
    std::string result = strip(s);
    BOOST_CHECK_EQUAL(result, "abc,def");

    s = "abc,def ";
    result = strip(s);
    BOOST_CHECK_EQUAL(result, "abc,def");

    s = " abc,def ";
    result = strip(s);
    BOOST_CHECK_EQUAL(result, "abc,def");

    s = "   abc,def   ";
    result = strip(s);
    BOOST_CHECK_EQUAL(result, "abc,def");

    s = ",abc,def,";
    result = strip(s, ",");
    BOOST_CHECK_EQUAL(result, "abc,def");
}

BOOST_AUTO_TEST_CASE(test_correct_split) {
    std::string s = "abc,def";

    std::vector<std::string> result;
    result = split(s, ',');
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc,def,";
    result = split(s, ',');
    BOOST_CHECK_EQUAL(result.size(), 3);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");
    BOOST_CHECK_EQUAL(result[2], "");

    s = "abc,,def";
    result = split(s, ',');
    BOOST_CHECK_EQUAL(result.size(), 3);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "");
    BOOST_CHECK_EQUAL(result[2], "def");

    s = "abc def";
    result = split(s, ' ');
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc  def";
    result = split(s, ' ');
    BOOST_CHECK_EQUAL(result.size(), 3);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "");
    BOOST_CHECK_EQUAL(result[2], "def");
}

BOOST_AUTO_TEST_CASE(test_correct_split_reg) {
    std::string s = "abc,def";

    std::vector<std::string> result;
    result = split_reg(s, ",");
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc,def,";
    result = split_reg(s, ",");
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc,,def";
    result = split_reg(s, ",");
    BOOST_CHECK_EQUAL(result.size(), 3);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "");
    BOOST_CHECK_EQUAL(result[2], "def");

    s = "abc def";
    result = split_reg(s, " ");
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc  def";
    result = split_reg(s, " +");
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");

    s = "abc def ";
    result = split_reg(s, " +");
    BOOST_CHECK_EQUAL(result.size(), 2);
    BOOST_CHECK_EQUAL(result[0], "abc");
    BOOST_CHECK_EQUAL(result[1], "def");
}

BOOST_AUTO_TEST_SUITE_END()


text:
#include "darknet.h"
#include "weights_visitor.h"

#include <dlib/cmd_line_parser.h>

using net_train_type = darknet::yolov4x_mish_train;
using net_infer_type = darknet::yolov4x_mish_infer;
// layer offset is 2 for yolov4x_mish yolov4_csp and scaled_yolov4, and 1 for the previous models
const unsigned int layer_offset = 2;

int main(const int argc, const char** argv)
try
{
    dlib::command_line_parser parser;
    parser.add_option("weights", "path to the darknet trained weights", 1);
    parser.add_option("num-classes", "number of classes to detect", 1);
    parser.add_option("img-size", "image size to process (default: 416)", 1);
    parser.add_option("print", "print out the network architecture");
    parser.add_option("save", "save network weights in dlib format", 1);
    parser.set_group_name("Help Options");
    parser.add_option("h", "alias for --help");
    parser.add_option("help", "display this message and exit");
    parser.parse(argc, argv);

    if (parser.option("h") or parser.option("help"))
    {
        parser.print_options();
        return EXIT_SUCCESS;
    }

    parser.check_sub_option("weights", "save");

    const long img_size = dlib::get_option(parser, "img-size", 416);
    const long num_classes = dlib::get_option(parser, "num-classes", 0);
    if (num_classes <= 0)
    {
        std::cout << "Specify the number of output classes with --num-classes\n";
        return EXIT_FAILURE;
    }
    const std::string weights_path = dlib::get_option(parser, "weights", "");
    if (weights_path.empty())
    {
        std::cout << "Specify the darknet weights with --weights\n";
        return EXIT_FAILURE;
    }

    net_train_type net_train;
    darknet::setup_detector<net_train_type, layer_offset>(net_train, num_classes, img_size);
    std::cout << "#params: " << dlib::count_parameters(net_train) << '\n';
    dlib::visit_layers_backwards(net_train, darknet::weights_visitor(weights_path));
    net_train.clean();
    net_infer_type net_infer = net_train;

    if (parser.option("save"))
    {
        dlib::serialize(parser.option("save").argument()) << net_infer;
    }

    if (parser.option("print"))
        std::cout << net_infer << '\n';

    return EXIT_SUCCESS;
}
catch (const std::exception& e)
{
    std::cout << e.what() << '\n';
    return EXIT_FAILURE;
}

max_stars_repo_name: dlibml/darknet

max_issues_repo_name: dlib-users/darknet

max_forks_repo_name: dlibml/darknet


text:
#ifndef CHAT_CLIENT_HPP
#define CHAT_CLIENT_HPP

#include <memory>
#include <string_view>
#include <string>
#include <mutex>

#include "Message.hpp"
#include "Utility.hpp"

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

// #ifndef UNIT_TESTS
using Stream_t = boost::asio::ip::tcp::socket;
// #else
// using Stream_t = MockAsyncStream;
// #endif

namespace client {
    template<class Stream>
    class Connection;

    using Connection_t = Connection<Stream_t>;
}

class Client final
    : public std::enable_shared_from_this<Client> {
public:
    enum class State {
        /**
         * This state indicates that
         * client is closed or disconnected.
         */
        CLOSED,
        /**
         * This state indicates that client is connected
         * but hasn't sent an ACK request to server
         */
        CONNECTED,
        /**
         * This state indicated that
         * client has sent SYN handshake to the
         * server and is waiting ACK response.
         */
        WAIT_ACK,
        /**
         * This state indicates that the client
         * has already received ACK from the
         * server and server was acknowledged
         * by the client.
         */
        RECEIVE_ACK,
        COUNT
    };

public:

    Client(
        std::shared_ptr<boost::asio::io_context> io,
        std::shared_ptr<boost::asio::ssl::context> sslContext
    );

    Client(const Client&) = delete;
    Client& operator=(const Client&) = delete;

    /**
     * Close connection if it's haven't been terminated yet.
     */
    ~Client();

    /**
     * Trying to connect to the remote host
     *
     * @param path
     *  It's ip address of the remote host
     * @param port
     *  It's a port on which a remote host is listening
     */
    void Connect(std::string_view path, std::string_view port);

    void CloseConnection();

    void HandleMessage(Internal::Response&&);

    /**
     * Write message to the remote peer
     * @param text
     *  Message in string format
     */
    void Write(std::string text);

    void SetState(State state) noexcept;

    State GetState() const noexcept;

    Internal::Response GetLastResponse() const noexcept;

private:
    std::shared_ptr<boost::asio::io_context>    m_io { nullptr };
    std::shared_ptr<boost::asio::ssl::context>  m_sslContext { nullptr };
    std::shared_ptr<client::Connection_t>       m_connection { nullptr };

    // TODO: move to some other intermediate type between client and GUI
    Internal::Response m_response;
    // TODO: maybe use atomic
    State m_state { State::CLOSED };
    mutable std::mutex m_mutex;
};

#endif // CHAT_CLIENT_HPP

max_stars_repo_name: Roout/char

max_issues_repo_name: Roout/char

max_forks_repo_name: Roout/char