Merge pull request #2746 from codablock/pr_v13_backport

[0.13.x] Backport multiple PRs from develop
This commit is contained in:
Alexander Block 2019-03-08 06:45:40 +01:00 committed by GitHub
commit 4d62f3c70e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 153 additions and 66 deletions

View File

@ -17,7 +17,7 @@
<string>APPL</string> <string>APPL</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string> <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@.@CLIENT_VERSION_BUILD@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers, 2014-@COPYRIGHT_YEAR@ @COPYRIGHT_HOLDERS_FINAL@</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@</string> <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@</string>

View File

@ -344,14 +344,16 @@ public:
}; };
template<typename Parent, typename CommitTarget>
class CDBTransaction { class CDBTransaction {
private: protected:
CDBWrapper &db; Parent &parent;
CommitTarget &commitTarget;
struct KeyHolder { struct KeyHolder {
virtual ~KeyHolder() = default; virtual ~KeyHolder() = default;
virtual bool Less(const KeyHolder &b) const = 0; virtual bool Less(const KeyHolder &b) const = 0;
virtual void Erase(CDBBatch &batch) = 0; virtual void Erase(CommitTarget &commitTarget) = 0;
}; };
typedef std::unique_ptr<KeyHolder> KeyHolderPtr; typedef std::unique_ptr<KeyHolder> KeyHolderPtr;
@ -364,15 +366,15 @@ private:
auto *b2 = dynamic_cast<const KeyHolderImpl<K>*>(&b); auto *b2 = dynamic_cast<const KeyHolderImpl<K>*>(&b);
return key < b2->key; return key < b2->key;
} }
virtual void Erase(CDBBatch &batch) { virtual void Erase(CommitTarget &commitTarget) {
batch.Erase(key); commitTarget.Erase(key);
} }
K key; K key;
}; };
struct KeyValueHolder { struct KeyValueHolder {
virtual ~KeyValueHolder() = default; virtual ~KeyValueHolder() = default;
virtual void Write(CDBBatch &batch) = 0; virtual void Write(CommitTarget &parent) = 0;
}; };
typedef std::unique_ptr<KeyValueHolder> KeyValueHolderPtr; typedef std::unique_ptr<KeyValueHolder> KeyValueHolderPtr;
@ -381,8 +383,13 @@ private:
KeyValueHolderImpl(const KeyHolderImpl<K> &_key, const V &_value) KeyValueHolderImpl(const KeyHolderImpl<K> &_key, const V &_value)
: key(_key), : key(_key),
value(_value) { } value(_value) { }
virtual void Write(CDBBatch &batch) { KeyValueHolderImpl(const KeyHolderImpl<K> &_key, V &&_value)
batch.Write(key.key, value); : key(_key),
value(std::forward<V>(_value)) { }
virtual void Write(CommitTarget &commitTarget) {
// we're moving the value instead of copying it. This means that Write() can only be called once per
// KeyValueHolderImpl instance. Commit() clears the write maps, so this ok.
commitTarget.Write(key.key, std::move(value));
} }
const KeyHolderImpl<K> &key; const KeyHolderImpl<K> &key;
V value; V value;
@ -422,22 +429,34 @@ private:
return getMapForType<K>(deletes, create); return getMapForType<K>(deletes, create);
} }
public: template <typename K, typename KV>
CDBTransaction(CDBWrapper &_db) : db(_db) {} void writeImpl(KeyHolderImpl<K>* k, KV&& kv) {
auto k2 = KeyHolderPtr(k);
template <typename K, typename V>
void Write(const K& key, const V& value) {
KeyHolderPtr k(new KeyHolderImpl<K>(key));
KeyHolderImpl<K>* k2 = dynamic_cast<KeyHolderImpl<K>*>(k.get());
KeyValueHolderPtr kv(new KeyValueHolderImpl<K,V>(*k2, value));
KeyValueMap *ds = getDeletesMap<K>(false); KeyValueMap *ds = getDeletesMap<K>(false);
if (ds) if (ds)
ds->erase(k); ds->erase(k2);
KeyValueMap *ws = getWritesMap<K>(true); KeyValueMap *ws = getWritesMap<K>(true);
ws->erase(k); ws->erase(k2);
ws->emplace(std::make_pair(std::move(k), std::move(kv))); ws->emplace(std::make_pair(std::move(k2), std::forward<KV>(kv)));
}
public:
CDBTransaction(Parent &_parent, CommitTarget &_commitTarget) : parent(_parent), commitTarget(_commitTarget) {}
template <typename K, typename V>
void Write(const K& key, const V& v) {
auto k = new KeyHolderImpl<K>(key);
auto kv = std::make_unique<KeyValueHolderImpl<K, V>>(*k, v);
writeImpl(k, std::move(kv));
}
template <typename K, typename V>
void Write(const K& key, V&& v) {
auto k = new KeyHolderImpl<K>(key);
auto kv = std::make_unique<KeyValueHolderImpl<K, typename std::remove_reference<V>::type>>(*k, std::forward<V>(v));
writeImpl(k, std::move(kv));
} }
template <typename K, typename V> template <typename K, typename V>
@ -450,7 +469,7 @@ public:
KeyValueMap *ws = getWritesMap<K>(false); KeyValueMap *ws = getWritesMap<K>(false);
if (ws) { if (ws) {
KeyValueMap::iterator it = ws->find(k); auto it = ws->find(k);
if (it != ws->end()) { if (it != ws->end()) {
auto *impl = dynamic_cast<KeyValueHolderImpl<K, V> *>(it->second.get()); auto *impl = dynamic_cast<KeyValueHolderImpl<K, V> *>(it->second.get());
if (!impl) if (!impl)
@ -460,7 +479,7 @@ public:
} }
} }
return db.Read(key, value); return parent.Read(key, value);
} }
template <typename K> template <typename K>
@ -475,7 +494,7 @@ public:
if (ws && ws->count(k)) if (ws && ws->count(k))
return true; return true;
return db.Exists(key); return parent.Exists(key);
} }
template <typename K> template <typename K>
@ -494,21 +513,18 @@ public:
deletes.clear(); deletes.clear();
} }
bool Commit() { void Commit() {
CDBBatch batch(db);
for (auto &p : deletes) { for (auto &p : deletes) {
for (auto &p2 : p.second) { for (auto &p2 : p.second) {
p2.first->Erase(batch); p2.first->Erase(commitTarget);
} }
} }
for (auto &p : writes) { for (auto &p : writes) {
for (auto &p2 : p.second) { for (auto &p2 : p.second) {
p2.second->Write(batch); p2.second->Write(commitTarget);
} }
} }
bool ret = db.WriteBatch(batch, true);
Clear(); Clear();
return ret;
} }
bool IsClean() { bool IsClean() {
@ -516,26 +532,29 @@ public:
} }
}; };
template<typename Parent, typename CommitTarget>
class CScopedDBTransaction { class CScopedDBTransaction {
public:
typedef CDBTransaction<Parent, CommitTarget> Transaction;
private: private:
CDBTransaction &dbTransaction; Transaction &dbTransaction;
std::function<void ()> commitHandler; std::function<void ()> commitHandler;
std::function<void ()> rollbackHandler; std::function<void ()> rollbackHandler;
bool didCommitOrRollback{}; bool didCommitOrRollback{};
public: public:
CScopedDBTransaction(CDBTransaction &dbTx) : dbTransaction(dbTx) {} CScopedDBTransaction(Transaction &dbTx) : dbTransaction(dbTx) {}
~CScopedDBTransaction() { ~CScopedDBTransaction() {
if (!didCommitOrRollback) if (!didCommitOrRollback)
Rollback(); Rollback();
} }
bool Commit() { void Commit() {
assert(!didCommitOrRollback); assert(!didCommitOrRollback);
didCommitOrRollback = true; didCommitOrRollback = true;
bool result = dbTransaction.Commit(); dbTransaction.Commit();
if (commitHandler) if (commitHandler)
commitHandler(); commitHandler();
return result;
} }
void Rollback() { void Rollback() {
assert(!didCommitOrRollback); assert(!didCommitOrRollback);
@ -545,9 +564,9 @@ public:
rollbackHandler(); rollbackHandler();
} }
static std::unique_ptr<CScopedDBTransaction> Begin(CDBTransaction &dbTx) { static std::unique_ptr<CScopedDBTransaction<Parent, CommitTarget>> Begin(Transaction &dbTx) {
assert(dbTx.IsClean()); assert(dbTx.IsClean());
return std::unique_ptr<CScopedDBTransaction>(new CScopedDBTransaction(dbTx)); return std::make_unique<CScopedDBTransaction<Parent, CommitTarget>>(dbTx);
} }
void SetCommitHandler(const std::function<void ()> &h) { void SetCommitHandler(const std::function<void ()> &h) {

View File

@ -83,6 +83,15 @@ void CDeterministicMN::ToJson(UniValue& obj) const
obj.push_back(Pair("proTxHash", proTxHash.ToString())); obj.push_back(Pair("proTxHash", proTxHash.ToString()));
obj.push_back(Pair("collateralHash", collateralOutpoint.hash.ToString())); obj.push_back(Pair("collateralHash", collateralOutpoint.hash.ToString()));
obj.push_back(Pair("collateralIndex", (int)collateralOutpoint.n)); obj.push_back(Pair("collateralIndex", (int)collateralOutpoint.n));
Coin coin;
if (GetUTXOCoin(collateralOutpoint, coin)) {
CTxDestination dest;
if (ExtractDestination(coin.out.scriptPubKey, dest)) {
obj.push_back(Pair("collateralAddress", CBitcoinAddress(dest).ToString()));
}
}
obj.push_back(Pair("operatorReward", (double)nOperatorReward / 100)); obj.push_back(Pair("operatorReward", (double)nOperatorReward / 100));
obj.push_back(Pair("state", stateObj)); obj.push_back(Pair("state", stateObj));
} }
@ -438,6 +447,13 @@ CDeterministicMNManager::CDeterministicMNManager(CEvoDB& _evoDb) :
bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& _state) bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& _state)
{ {
AssertLockHeld(cs_main);
bool fDIP0003Active = VersionBitsState(pindex->pprev, Params().GetConsensus(), Consensus::DEPLOYMENT_DIP0003, versionbitscache) == THRESHOLD_ACTIVE;
if (!fDIP0003Active) {
return true;
}
LOCK(cs); LOCK(cs);
int nHeight = pindex->nHeight; int nHeight = pindex->nHeight;
@ -457,7 +473,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde
CDeterministicMNListDiff diff = oldList.BuildDiff(newList); CDeterministicMNListDiff diff = oldList.BuildDiff(newList);
evoDb.Write(std::make_pair(DB_LIST_DIFF, diff.blockHash), diff); evoDb.Write(std::make_pair(DB_LIST_DIFF, diff.blockHash), diff);
if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0) { if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0 || oldList.GetHeight() == -1) {
evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, diff.blockHash), newList); evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, diff.blockHash), newList);
LogPrintf("CDeterministicMNManager::%s -- Wrote snapshot. nHeight=%d, mapCurMNs.allMNsCount=%d\n", LogPrintf("CDeterministicMNManager::%s -- Wrote snapshot. nHeight=%d, mapCurMNs.allMNsCount=%d\n",
__func__, nHeight, newList.GetAllMNsCount()); __func__, nHeight, newList.GetAllMNsCount());

View File

@ -8,10 +8,21 @@ CEvoDB* evoDb;
CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) : CEvoDB::CEvoDB(size_t nCacheSize, bool fMemory, bool fWipe) :
db(fMemory ? "" : (GetDataDir() / "evodb"), nCacheSize, fMemory, fWipe), db(fMemory ? "" : (GetDataDir() / "evodb"), nCacheSize, fMemory, fWipe),
dbTransaction(db) rootBatch(db),
rootDBTransaction(db, rootBatch),
curDBTransaction(rootDBTransaction, rootDBTransaction)
{ {
} }
bool CEvoDB::CommitRootTransaction()
{
assert(curDBTransaction.IsClean());
rootDBTransaction.Commit();
bool ret = db.WriteBatch(rootBatch);
rootBatch.Clear();
return ret;
}
bool CEvoDB::VerifyBestBlock(const uint256& hash) bool CEvoDB::VerifyBestBlock(const uint256& hash)
{ {
// Make sure evodb is consistent. // Make sure evodb is consistent.

View File

@ -16,15 +16,22 @@ class CEvoDB
private: private:
CCriticalSection cs; CCriticalSection cs;
CDBWrapper db; CDBWrapper db;
CDBTransaction dbTransaction;
typedef CDBTransaction<CDBWrapper, CDBBatch> RootTransaction;
typedef CDBTransaction<RootTransaction, RootTransaction> CurTransaction;
typedef CScopedDBTransaction<RootTransaction, RootTransaction> ScopedTransaction;
CDBBatch rootBatch;
RootTransaction rootDBTransaction;
CurTransaction curDBTransaction;
public: public:
CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
std::unique_ptr<CScopedDBTransaction> BeginTransaction() std::unique_ptr<ScopedTransaction> BeginTransaction()
{ {
LOCK(cs); LOCK(cs);
auto t = CScopedDBTransaction::Begin(dbTransaction); auto t = ScopedTransaction::Begin(curDBTransaction);
return t; return t;
} }
@ -32,28 +39,28 @@ public:
bool Read(const K& key, V& value) bool Read(const K& key, V& value)
{ {
LOCK(cs); LOCK(cs);
return dbTransaction.Read(key, value); return curDBTransaction.Read(key, value);
} }
template <typename K, typename V> template <typename K, typename V>
void Write(const K& key, const V& value) void Write(const K& key, const V& value)
{ {
LOCK(cs); LOCK(cs);
dbTransaction.Write(key, value); curDBTransaction.Write(key, value);
} }
template <typename K> template <typename K>
bool Exists(const K& key) bool Exists(const K& key)
{ {
LOCK(cs); LOCK(cs);
return dbTransaction.Exists(key); return curDBTransaction.Exists(key);
} }
template <typename K> template <typename K>
void Erase(const K& key) void Erase(const K& key)
{ {
LOCK(cs); LOCK(cs);
dbTransaction.Erase(key); curDBTransaction.Erase(key);
} }
CDBWrapper& GetRawDB() CDBWrapper& GetRawDB()
@ -61,6 +68,8 @@ public:
return db; return db;
} }
bool CommitRootTransaction();
bool VerifyBestBlock(const uint256& hash); bool VerifyBestBlock(const uint256& hash);
void WriteBestBlock(const uint256& hash); void WriteBestBlock(const uint256& hash);
}; };

View File

@ -119,25 +119,27 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
mnListDiffRet = CSimplifiedMNListDiff(); mnListDiffRet = CSimplifiedMNListDiff();
BlockMap::iterator baseBlockIt = mapBlockIndex.begin(); const CBlockIndex* baseBlockIndex = chainActive.Genesis();
if (!baseBlockHash.IsNull()) { if (!baseBlockHash.IsNull()) {
baseBlockIt = mapBlockIndex.find(baseBlockHash); auto it = mapBlockIndex.find(baseBlockHash);
} if (it == mapBlockIndex.end()) {
auto blockIt = mapBlockIndex.find(blockHash);
if (baseBlockIt == mapBlockIndex.end()) {
errorRet = strprintf("block %s not found", baseBlockHash.ToString()); errorRet = strprintf("block %s not found", baseBlockHash.ToString());
return false; return false;
} }
baseBlockIndex = it->second;
}
auto blockIt = mapBlockIndex.find(blockHash);
if (blockIt == mapBlockIndex.end()) { if (blockIt == mapBlockIndex.end()) {
errorRet = strprintf("block %s not found", blockHash.ToString()); errorRet = strprintf("block %s not found", blockHash.ToString());
return false; return false;
} }
const CBlockIndex* blockIndex = blockIt->second;
if (!chainActive.Contains(baseBlockIt->second) || !chainActive.Contains(blockIt->second)) { if (!chainActive.Contains(baseBlockIndex) || !chainActive.Contains(blockIndex)) {
errorRet = strprintf("block %s and %s are not in the same chain", baseBlockHash.ToString(), blockHash.ToString()); errorRet = strprintf("block %s and %s are not in the same chain", baseBlockHash.ToString(), blockHash.ToString());
return false; return false;
} }
if (baseBlockIt->second->nHeight > blockIt->second->nHeight) { if (baseBlockIndex->nHeight > blockIndex->nHeight) {
errorRet = strprintf("base block %s is higher then block %s", baseBlockHash.ToString(), blockHash.ToString()); errorRet = strprintf("base block %s is higher then block %s", baseBlockHash.ToString(), blockHash.ToString());
return false; return false;
} }
@ -150,7 +152,7 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc
// TODO store coinbase TX in CBlockIndex // TODO store coinbase TX in CBlockIndex
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, blockIt->second, Params().GetConsensus())) { if (!ReadBlockFromDisk(block, blockIndex, Params().GetConsensus())) {
errorRet = strprintf("failed to read block %s from disk", blockHash.ToString()); errorRet = strprintf("failed to read block %s from disk", blockHash.ToString());
return false; return false;
} }

View File

@ -256,6 +256,10 @@ void PrepareShutdown()
MapPort(false); MapPort(false);
UnregisterValidationInterface(peerLogic.get()); UnregisterValidationInterface(peerLogic.get());
peerLogic.reset(); peerLogic.reset();
if (g_connman) {
// make sure to stop all threads before g_connman is reset to nullptr as these threads might still be accessing it
g_connman->Stop();
}
g_connman.reset(); g_connman.reset();
if (!fLiteMode && !fRPCInWarmup) { if (!fLiteMode && !fRPCInWarmup) {
@ -1963,7 +1967,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError(_("Invalid masternodeblsprivkey. Please see documenation.")); return InitError(_("Invalid masternodeblsprivkey. Please see documenation."));
} }
} else { } else {
InitWarning(_("You should specify a masternodeblsprivkey in the configuration. Please see documentation for help.")); return InitError(_("You must specify a masternodeblsprivkey in the configuration. Please see documentation for help."));
} }
// init and register activeMasternodeManager // init and register activeMasternodeManager

View File

@ -19,10 +19,24 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
vMatch.reserve(block.vtx.size()); vMatch.reserve(block.vtx.size());
vHashes.reserve(block.vtx.size()); vHashes.reserve(block.vtx.size());
const static std::set<int> allowedTxTypes = {
TRANSACTION_NORMAL,
TRANSACTION_PROVIDER_REGISTER,
TRANSACTION_PROVIDER_UPDATE_SERVICE,
TRANSACTION_PROVIDER_UPDATE_REGISTRAR,
TRANSACTION_PROVIDER_UPDATE_REVOKE,
TRANSACTION_COINBASE,
};
for (unsigned int i = 0; i < block.vtx.size(); i++) for (unsigned int i = 0; i < block.vtx.size(); i++)
{ {
const uint256& hash = block.vtx[i]->GetHash(); const auto& tx = *block.vtx[i];
if (filter.IsRelevantAndUpdate(*block.vtx[i])) if (tx.nVersion == 3 && !allowedTxTypes.count(tx.nType)) {
continue;
}
const uint256& hash = tx.GetHash();
if (filter.IsRelevantAndUpdate(tx))
{ {
vMatch.push_back(true); vMatch.push_back(true);
vMatchedTxn.push_back(std::make_pair(i, hash)); vMatchedTxn.push_back(std::make_pair(i, hash));

View File

@ -890,17 +890,26 @@ UniValue masternodelist(const JSONRPCRequest& request)
std::string strOutpoint = mnpair.first.ToStringShort(); std::string strOutpoint = mnpair.first.ToStringShort();
CScript payeeScript; CScript payeeScript;
std::string collateralAddressStr = "UNKNOWN";
if (deterministicMNManager->IsDeterministicMNsSporkActive()) { if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
auto dmn = deterministicMNManager->GetListAtChainTip().GetMNByCollateral(mn.outpoint); auto dmn = deterministicMNManager->GetListAtChainTip().GetMNByCollateral(mn.outpoint);
if (dmn) { if (dmn) {
payeeScript = dmn->pdmnState->scriptPayout; payeeScript = dmn->pdmnState->scriptPayout;
Coin coin;
if (GetUTXOCoin(dmn->collateralOutpoint, coin)) {
CTxDestination collateralDest;
if (ExtractDestination(coin.out.scriptPubKey, collateralDest)) {
collateralAddressStr = CBitcoinAddress(collateralDest).ToString();
}
}
} }
} else { } else {
payeeScript = GetScriptForDestination(mn.keyIDCollateralAddress); payeeScript = GetScriptForDestination(mn.keyIDCollateralAddress);
collateralAddressStr = CBitcoinAddress(mn.keyIDCollateralAddress).ToString();
} }
CTxDestination payeeDest; CTxDestination payeeDest;
std::string payeeStr = "UNKOWN"; std::string payeeStr = "UNKNOWN";
if (ExtractDestination(payeeScript, payeeDest)) { if (ExtractDestination(payeeScript, payeeDest)) {
payeeStr = CBitcoinAddress(payeeDest).ToString(); payeeStr = CBitcoinAddress(payeeDest).ToString();
} }
@ -965,7 +974,8 @@ UniValue masternodelist(const JSONRPCRequest& request)
(int64_t)mn.lastPing.sigTime << " " << (int64_t)mn.lastPing.sigTime << " " <<
(int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " << (int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " <<
mn.GetLastPaidTime() << " " << mn.GetLastPaidTime() << " " <<
mn.GetLastPaidBlock(); mn.GetLastPaidBlock() << " " <<
collateralAddressStr;
std::string strInfo = streamInfo.str(); std::string strInfo = streamInfo.str();
if (strFilter !="" && strInfo.find(strFilter) == std::string::npos && if (strFilter !="" && strInfo.find(strFilter) == std::string::npos &&
strOutpoint.find(strFilter) == std::string::npos) continue; strOutpoint.find(strFilter) == std::string::npos) continue;
@ -983,6 +993,7 @@ UniValue masternodelist(const JSONRPCRequest& request)
objMN.push_back(Pair("lastpaidblock", mn.GetLastPaidBlock())); objMN.push_back(Pair("lastpaidblock", mn.GetLastPaidBlock()));
objMN.push_back(Pair("owneraddress", CBitcoinAddress(mn.keyIDOwner).ToString())); objMN.push_back(Pair("owneraddress", CBitcoinAddress(mn.keyIDOwner).ToString()));
objMN.push_back(Pair("votingaddress", CBitcoinAddress(mn.keyIDVoting).ToString())); objMN.push_back(Pair("votingaddress", CBitcoinAddress(mn.keyIDVoting).ToString()));
objMN.push_back(Pair("collateraladdress", collateralAddressStr));
obj.push_back(Pair(strOutpoint, objMN)); obj.push_back(Pair(strOutpoint, objMN));
} else if (strMode == "keyid") { } else if (strMode == "keyid") {
if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue; if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;

View File

@ -693,7 +693,7 @@ UniValue protx_update_registrar(const JSONRPCRequest& request)
ptx.pubKeyOperator = ParseBLSPubKey(request.params[2].get_str(), "operator BLS address"); ptx.pubKeyOperator = ParseBLSPubKey(request.params[2].get_str(), "operator BLS address");
} }
if (request.params[3].get_str() != "") { if (request.params[3].get_str() != "") {
ptx.keyIDVoting = ParsePubKeyIDFromAddress(request.params[3].get_str(), "operator address"); ptx.keyIDVoting = ParsePubKeyIDFromAddress(request.params[3].get_str(), "voting address");
} }
CBitcoinAddress payoutAddress(request.params[4].get_str()); CBitcoinAddress payoutAddress(request.params[4].get_str());

View File

@ -2414,6 +2414,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode, int n
// Flush the chainstate (which may refer to block index entries). // Flush the chainstate (which may refer to block index entries).
if (!pcoinsTip->Flush()) if (!pcoinsTip->Flush())
return AbortNode(state, "Failed to write to coin database"); return AbortNode(state, "Failed to write to coin database");
if (!evoDb->CommitRootTransaction()) {
return AbortNode(state, "Failed to commit EvoDB");
}
nLastFlush = nNow; nLastFlush = nNow;
} }
if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) { if (fDoFullFlush || ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000)) {
@ -2519,12 +2522,11 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
bool flushed = view.Flush(); bool flushed = view.Flush();
assert(flushed); assert(flushed);
bool committed = dbTx->Commit(); dbTx->Commit();
assert(committed);
} }
LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(state, IsInitialBlockDownload() ? FLUSH_STATE_IF_NEEDED : FLUSH_STATE_ALWAYS)) if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false; return false;
// Resurrect mempool transactions from the disconnected block. // Resurrect mempool transactions from the disconnected block.
std::vector<uint256> vHashUpdate; std::vector<uint256> vHashUpdate;
@ -2609,13 +2611,12 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001); LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
bool flushed = view.Flush(); bool flushed = view.Flush();
assert(flushed); assert(flushed);
bool committed = dbTx->Commit(); dbTx->Commit();
assert(committed);
} }
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001); LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(state, IsInitialBlockDownload() ? FLUSH_STATE_IF_NEEDED : FLUSH_STATE_ALWAYS)) if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false; return false;
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);