mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Refactor few things here and there (#3066)
* Refactor `HandleFullyConfirmedBlock()` * Pass `pindexMined` into `AddNonLockedTx()` * Unify time import in Dash specific tests * Refactor UpdateSpork and SetPrivKey
This commit is contained in:
parent
f2dcac3a4f
commit
9abc393839
@ -983,8 +983,7 @@ void CInstantSendManager::ProcessNewTransaction(const CTransactionRef& tx, const
|
||||
LOCK(cs);
|
||||
if (!chainlocked && islockHash.IsNull()) {
|
||||
// TX is not locked, so make sure it is tracked
|
||||
AddNonLockedTx(tx);
|
||||
nonLockedTxs.at(tx->GetHash()).pindexMined = pindex;
|
||||
AddNonLockedTx(tx, pindex);
|
||||
} else {
|
||||
// TX is locked, so make sure we don't track it anymore
|
||||
RemoveNonLockedTx(tx->GetHash(), true);
|
||||
@ -1025,11 +1024,12 @@ void CInstantSendManager::BlockDisconnected(const std::shared_ptr<const CBlock>&
|
||||
}
|
||||
}
|
||||
|
||||
void CInstantSendManager::AddNonLockedTx(const CTransactionRef& tx)
|
||||
void CInstantSendManager::AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
auto res = nonLockedTxs.emplace(tx->GetHash(), NonLockedTxInfo());
|
||||
auto& info = res.first->second;
|
||||
info.pindexMined = pindexMined;
|
||||
|
||||
if (!info.tx) {
|
||||
info.tx = tx;
|
||||
@ -1123,50 +1123,48 @@ void CInstantSendManager::UpdatedBlockTip(const CBlockIndex* pindexNew)
|
||||
|
||||
void CInstantSendManager::HandleFullyConfirmedBlock(const CBlockIndex* pindex)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
auto& consensusParams = Params().GetConsensus();
|
||||
|
||||
std::unordered_map<uint256, CInstantSendLockPtr> removeISLocks;
|
||||
{
|
||||
LOCK(cs);
|
||||
auto removeISLocks = db.RemoveConfirmedInstantSendLocks(pindex->nHeight);
|
||||
|
||||
removeISLocks = db.RemoveConfirmedInstantSendLocks(pindex->nHeight);
|
||||
if (pindex->nHeight > 100) {
|
||||
db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100);
|
||||
}
|
||||
for (auto& p : removeISLocks) {
|
||||
auto& islockHash = p.first;
|
||||
auto& islock = p.second;
|
||||
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: removed islock as it got fully confirmed\n", __func__,
|
||||
islock->txid.ToString(), islockHash.ToString());
|
||||
if (pindex->nHeight > 100) {
|
||||
db.RemoveArchivedInstantSendLocks(pindex->nHeight - 100);
|
||||
}
|
||||
for (auto& p : removeISLocks) {
|
||||
auto& islockHash = p.first;
|
||||
auto& islock = p.second;
|
||||
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: removed islock as it got fully confirmed\n", __func__,
|
||||
islock->txid.ToString(), islockHash.ToString());
|
||||
|
||||
for (auto& in : islock->inputs) {
|
||||
auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in));
|
||||
inputRequestIds.erase(inputRequestId);
|
||||
for (auto& in : islock->inputs) {
|
||||
auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in));
|
||||
inputRequestIds.erase(inputRequestId);
|
||||
|
||||
// no need to keep recovered sigs for fully confirmed IS locks, as there is no chance for conflicts
|
||||
// from now on. All inputs are spent now and can't be spend in any other TX.
|
||||
quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, inputRequestId);
|
||||
}
|
||||
|
||||
// same as in the loop
|
||||
quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, islock->GetRequestId());
|
||||
// no need to keep recovered sigs for fully confirmed IS locks, as there is no chance for conflicts
|
||||
// from now on. All inputs are spent now and can't be spend in any other TX.
|
||||
quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, inputRequestId);
|
||||
}
|
||||
|
||||
// Find all previously unlocked TXs that got locked by this fully confirmed (ChainLock) block and remove them
|
||||
// from the nonLockedTxs map. Also collect all children of these TXs and mark them for retrying of IS locking.
|
||||
std::vector<uint256> toRemove;
|
||||
for (auto& p : nonLockedTxs) {
|
||||
auto pindexMined = p.second.pindexMined;
|
||||
// same as in the loop
|
||||
quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, islock->GetRequestId());
|
||||
}
|
||||
|
||||
if (pindexMined && pindex->GetAncestor(pindexMined->nHeight) == pindexMined) {
|
||||
toRemove.emplace_back(p.first);
|
||||
}
|
||||
}
|
||||
for (auto& txid : toRemove) {
|
||||
// This will also add children to pendingRetryTxs
|
||||
RemoveNonLockedTx(txid, true);
|
||||
// Find all previously unlocked TXs that got locked by this fully confirmed (ChainLock) block and remove them
|
||||
// from the nonLockedTxs map. Also collect all children of these TXs and mark them for retrying of IS locking.
|
||||
std::vector<uint256> toRemove;
|
||||
for (auto& p : nonLockedTxs) {
|
||||
auto pindexMined = p.second.pindexMined;
|
||||
|
||||
if (pindexMined && pindex->GetAncestor(pindexMined->nHeight) == pindexMined) {
|
||||
toRemove.emplace_back(p.first);
|
||||
}
|
||||
}
|
||||
for (auto& txid : toRemove) {
|
||||
// This will also add children to pendingRetryTxs
|
||||
RemoveNonLockedTx(txid, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CInstantSendManager::RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock)
|
||||
|
@ -145,7 +145,8 @@ public:
|
||||
void TransactionAddedToMempool(const CTransactionRef& tx);
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted);
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected);
|
||||
void AddNonLockedTx(const CTransactionRef& tx);
|
||||
|
||||
void AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined);
|
||||
void RemoveNonLockedTx(const uint256& txid, bool retryChildren);
|
||||
void RemoveConflictedTx(const CTransaction& tx);
|
||||
|
||||
|
@ -197,23 +197,27 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn
|
||||
{
|
||||
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
bool fSpork6IsActive = IsSporkActive(SPORK_6_NEW_SIGS);
|
||||
if(spork.Sign(sporkPrivKey, fSpork6IsActive)) {
|
||||
CKeyID keyIDSigner;
|
||||
if (!spork.GetSignerKeyID(keyIDSigner, fSpork6IsActive) || !setSporkPubKeyIDs.count(keyIDSigner)) {
|
||||
LogPrintf("CSporkManager::UpdateSpork: failed to find keyid for private key\n");
|
||||
return false;
|
||||
}
|
||||
{
|
||||
LOCK(cs);
|
||||
mapSporksByHash[spork.GetHash()] = spork;
|
||||
mapSporksActive[nSporkID][keyIDSigner] = spork;
|
||||
}
|
||||
spork.Relay(connman);
|
||||
return true;
|
||||
if (!spork.Sign(sporkPrivKey, fSpork6IsActive)) {
|
||||
LogPrintf("CSporkManager::%s -- ERROR: signing failed for spork %d\n", __func__, nSporkID);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
CKeyID keyIDSigner;
|
||||
if (!spork.GetSignerKeyID(keyIDSigner, fSpork6IsActive) || !setSporkPubKeyIDs.count(keyIDSigner)) {
|
||||
LogPrintf("CSporkManager::UpdateSpork: failed to find keyid for private key\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CSporkManager::%s -- signed %d %s\n", __func__, nSporkID, spork.GetHash().ToString());
|
||||
|
||||
mapSporksByHash[spork.GetHash()] = spork;
|
||||
mapSporksActive[nSporkID][keyIDSigner] = spork;
|
||||
|
||||
spork.Relay(connman);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSporkManager::IsSporkActive(SporkId nSporkID)
|
||||
@ -312,17 +316,16 @@ bool CSporkManager::SetPrivKey(const std::string& strPrivKey)
|
||||
}
|
||||
|
||||
CSporkMessage spork;
|
||||
if (spork.Sign(key, IsSporkActive(SPORK_6_NEW_SIGS))) {
|
||||
LOCK(cs);
|
||||
// Test signing successful, proceed
|
||||
LogPrintf("CSporkManager::SetPrivKey -- Successfully initialized as spork signer\n");
|
||||
|
||||
sporkPrivKey = key;
|
||||
return true;
|
||||
} else {
|
||||
if (!spork.Sign(key, IsSporkActive(SPORK_6_NEW_SIGS))) {
|
||||
LogPrintf("CSporkManager::SetPrivKey -- Test signing failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test signing successful, proceed
|
||||
LOCK(cs);
|
||||
LogPrintf("CSporkManager::SetPrivKey -- Successfully initialized as spork signer\n");
|
||||
sporkPrivKey = key;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CSporkManager::ToString() const
|
||||
|
@ -7,7 +7,6 @@ from collections import namedtuple
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
dip4-coinbasemerkleroots.py
|
||||
|
@ -3,10 +3,11 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import time
|
||||
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
llmq-chainlocks.py
|
||||
@ -77,10 +78,10 @@ class LLMQChainLocksTest(DashTestFramework):
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
# Now try to reorg the chain
|
||||
self.nodes[0].generate(2)
|
||||
sleep(6)
|
||||
time.sleep(6)
|
||||
assert(self.nodes[1].getbestblockhash() == good_tip)
|
||||
self.nodes[0].generate(2)
|
||||
sleep(6)
|
||||
time.sleep(6)
|
||||
assert(self.nodes[1].getbestblockhash() == good_tip)
|
||||
|
||||
# Now let the node which is on the wrong chain reorg back to the locked chain
|
||||
@ -106,7 +107,7 @@ class LLMQChainLocksTest(DashTestFramework):
|
||||
for txid in txs:
|
||||
tx = self.nodes[0].getrawtransaction(txid, 1)
|
||||
assert("confirmations" not in tx)
|
||||
sleep(1)
|
||||
time.sleep(1)
|
||||
assert(not self.nodes[0].getblock(self.nodes[0].getbestblockhash())["chainlock"])
|
||||
# Disable LLMQ based InstantSend for a very short time (this never gets propagated to other nodes)
|
||||
self.nodes[0].spork("SPORK_2_INSTANTSEND_ENABLED", 4070908800)
|
||||
@ -132,8 +133,8 @@ class LLMQChainLocksTest(DashTestFramework):
|
||||
self.wait_for_chainlock(node, tip)
|
||||
|
||||
def wait_for_chainlock(self, node, block_hash):
|
||||
t = time()
|
||||
while time() - t < 15:
|
||||
t = time.time()
|
||||
while time.time() - t < 15:
|
||||
try:
|
||||
block = node.getblock(block_hash)
|
||||
if block["confirmations"] > 0 and block["chainlock"]:
|
||||
@ -141,7 +142,7 @@ class LLMQChainLocksTest(DashTestFramework):
|
||||
except:
|
||||
# block might not be on the node yet
|
||||
pass
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
raise AssertionError("wait_for_chainlock timed out")
|
||||
|
||||
def create_chained_txs(self, node, amount):
|
||||
|
@ -2,11 +2,12 @@
|
||||
# Copyright (c) 2015-2018 The Dash Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
import time
|
||||
|
||||
from test_framework.blocktools import get_masternode_payment, create_coinbase, create_block
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
llmq-is-cl-conflicts.py
|
||||
@ -113,7 +114,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
|
||||
# Give the CLSIG some time to propagate. We unfortunately can't check propagation here as "getblock/getblockheader"
|
||||
# is required to check for CLSIGs, but this requires the block header to be propagated already
|
||||
sleep(1)
|
||||
time.sleep(1)
|
||||
|
||||
# The block should get accepted now, and at the same time prune the conflicting ISLOCKs
|
||||
submit_result = self.nodes[1].submitblock(ToHex(block))
|
||||
@ -183,7 +184,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
# Send the ISLOCK, which should result in the last 2 blocks to be invalidated, even though the nodes don't know
|
||||
# the locked transaction yet
|
||||
self.test_node.send_islock(islock)
|
||||
sleep(5)
|
||||
time.sleep(5)
|
||||
|
||||
assert(self.nodes[0].getbestblockhash() == good_tip)
|
||||
assert(self.nodes[1].getbestblockhash() == good_tip)
|
||||
@ -210,8 +211,8 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
self.wait_for_chainlock(node, tip)
|
||||
|
||||
def wait_for_chainlock(self, node, block_hash):
|
||||
t = time()
|
||||
while time() - t < 15:
|
||||
t = time.time()
|
||||
while time.time() - t < 15:
|
||||
try:
|
||||
block = node.getblockheader(block_hash)
|
||||
if block["confirmations"] > 0 and block["chainlock"]:
|
||||
@ -219,7 +220,7 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
except:
|
||||
# block might not be on the node yet
|
||||
pass
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
raise AssertionError("wait_for_chainlock timed out")
|
||||
|
||||
def create_block(self, node, vtx=[]):
|
||||
@ -293,13 +294,13 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
|
||||
recSig = None
|
||||
|
||||
t = time()
|
||||
while time() - t < 10:
|
||||
t = time.time()
|
||||
while time.time() - t < 10:
|
||||
try:
|
||||
recSig = self.nodes[0].quorum('getrecsig', 100, request_id, message_hash)
|
||||
break
|
||||
except:
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
assert(recSig is not None)
|
||||
|
||||
clsig = msg_clsig(height, blockHash, hex_str_to_bytes(recSig['sig']))
|
||||
@ -322,13 +323,13 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
|
||||
|
||||
recSig = None
|
||||
|
||||
t = time()
|
||||
while time() - t < 10:
|
||||
t = time.time()
|
||||
while time.time() - t < 10:
|
||||
try:
|
||||
recSig = self.nodes[0].quorum('getrecsig', 100, request_id, message_hash)
|
||||
break
|
||||
except:
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
assert(recSig is not None)
|
||||
|
||||
islock = msg_islock(inputs, tx.sha256, hex_str_to_bytes(recSig['sig']))
|
||||
|
@ -3,10 +3,11 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import time
|
||||
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
llmq-signing.py
|
||||
@ -41,18 +42,18 @@ class LLMQSigningTest(DashTestFramework):
|
||||
return True
|
||||
|
||||
def wait_for_sigs(hasrecsigs, isconflicting1, isconflicting2, timeout):
|
||||
t = time()
|
||||
while time() - t < timeout:
|
||||
t = time.time()
|
||||
while time.time() - t < timeout:
|
||||
if check_sigs(hasrecsigs, isconflicting1, isconflicting2):
|
||||
return
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
raise AssertionError("wait_for_sigs timed out")
|
||||
|
||||
def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout):
|
||||
t = time()
|
||||
while time() - t < timeout:
|
||||
t = time.time()
|
||||
while time.time() - t < timeout:
|
||||
assert(check_sigs(hasrecsigs, isconflicting1, isconflicting2))
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
|
||||
# Initial state
|
||||
wait_for_sigs(False, False, False, 1)
|
||||
|
@ -3,9 +3,10 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import time
|
||||
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
llmq-simplepose.py
|
||||
@ -36,8 +37,8 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
self.stop_node(mn.nodeIdx)
|
||||
self.nodes.remove(mn.node)
|
||||
|
||||
t = time()
|
||||
while (not self.check_punished(mn) or not self.check_banned(mn)) and (time() - t) < 120:
|
||||
t = time.time()
|
||||
while (not self.check_punished(mn) or not self.check_banned(mn)) and (time.time() - t) < 120:
|
||||
self.mine_quorum(expected_contributions=i-1, expected_complaints=i-1, expected_commitments=i-1)
|
||||
|
||||
assert(self.check_punished(mn) and self.check_banned(mn))
|
||||
|
@ -2,11 +2,11 @@
|
||||
# Copyright (c) 2018 The Dash Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
import time
|
||||
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
multikeysporks.py
|
||||
@ -105,15 +105,15 @@ class MultiKeySporkTest(BitcoinTestFramework):
|
||||
node.spork('SPORK_2_INSTANTSEND_ENABLED', value)
|
||||
|
||||
def wait_for_test_spork_state(self, node, value):
|
||||
start = time()
|
||||
start = time.time()
|
||||
got_state = False
|
||||
while True:
|
||||
if self.get_test_spork_state(node) == value:
|
||||
got_state = True
|
||||
break
|
||||
if time() > start + 10:
|
||||
if time.time() > start + 10:
|
||||
break
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
return got_state
|
||||
|
||||
def run_test(self):
|
||||
|
@ -6,7 +6,6 @@
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
InstantSendTest -- test InstantSend functionality (prevent doublespend for unconfirmed transactions)
|
||||
|
@ -2,11 +2,11 @@
|
||||
# Copyright (c) 2018 The Dash Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
import time
|
||||
|
||||
from test_framework.mininode import *
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
from time import *
|
||||
|
||||
'''
|
||||
'''
|
||||
@ -45,15 +45,15 @@ class SporkTest(BitcoinTestFramework):
|
||||
|
||||
# check spork propagation for connected nodes
|
||||
self.set_test_spork_state(self.nodes[0], True)
|
||||
start = time()
|
||||
start = time.time()
|
||||
sent = False
|
||||
while True:
|
||||
if self.get_test_spork_state(self.nodes[1]):
|
||||
sent = True
|
||||
break
|
||||
if time() > start + 10:
|
||||
if time.time() > start + 10:
|
||||
break
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
assert(sent)
|
||||
|
||||
# restart nodes to check spork persistence
|
||||
@ -72,15 +72,15 @@ class SporkTest(BitcoinTestFramework):
|
||||
|
||||
# connect new node and check spork propagation after restoring from cache
|
||||
connect_nodes(self.nodes[1], 2)
|
||||
start = time()
|
||||
start = time.time()
|
||||
sent = False
|
||||
while True:
|
||||
if self.get_test_spork_state(self.nodes[2]):
|
||||
sent = True
|
||||
break
|
||||
if time() > start + 10:
|
||||
if time.time() > start + 10:
|
||||
break
|
||||
sleep(0.1)
|
||||
time.sleep(0.1)
|
||||
assert(sent)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user