mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
cancel out conflicting locks
This commit is contained in:
parent
c3b92a7103
commit
97d73a72b5
@ -104,11 +104,13 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
|
|||||||
if (i != mapTxLocks.end()){
|
if (i != mapTxLocks.end()){
|
||||||
//we only care if we have a complete tx lock
|
//we only care if we have a complete tx lock
|
||||||
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
||||||
LogPrintf("ProcessMessageInstantX::txlreq - Found Existing Complete IX Lock\n");
|
if(!CheckForConflictingLocks(tx)){
|
||||||
|
LogPrintf("ProcessMessageInstantX::txlreq - Found Existing Complete IX Lock\n");
|
||||||
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
DisconnectBlockAndInputs(state, tx);
|
DisconnectBlockAndInputs(state, tx);
|
||||||
mapTxLockReq.insert(make_pair(tx.GetHash(), tx));
|
mapTxLockReq.insert(make_pair(tx.GetHash(), tx));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +231,7 @@ int64_t CreateNewLock(CTransaction tx)
|
|||||||
|
|
||||||
CTransactionLock newLock;
|
CTransactionLock newLock;
|
||||||
newLock.nBlockHeight = nBlockHeight;
|
newLock.nBlockHeight = nBlockHeight;
|
||||||
newLock.nExpiration = GetTime()+(60*60);
|
newLock.nExpiration = GetTime()+(60*15); //locks expire after 15 minutes (6 confirmations)
|
||||||
newLock.nTimeout = GetTime()+(60*5);
|
newLock.nTimeout = GetTime()+(60*5);
|
||||||
newLock.txHash = tx.GetHash();
|
newLock.txHash = tx.GetHash();
|
||||||
mapTxLocks.insert(make_pair(tx.GetHash(), newLock));
|
mapTxLocks.insert(make_pair(tx.GetHash(), newLock));
|
||||||
@ -318,29 +320,32 @@ bool ProcessConsensusVote(CConsensusVote& ctx)
|
|||||||
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
||||||
if(fDebug) LogPrintf("InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s !\n", (*i).second.GetHash().ToString().c_str());
|
if(fDebug) LogPrintf("InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s !\n", (*i).second.GetHash().ToString().c_str());
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
CTransaction& tx = mapTxLockReq[ctx.txHash];
|
||||||
if(pwalletMain){
|
if(!CheckForConflictingLocks(tx)){
|
||||||
if(pwalletMain->UpdatedTransaction((*i).second.txHash)){
|
|
||||||
nCompleteTXLocks++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(mapTxLockReq.count(ctx.txHash)){
|
#ifdef ENABLE_WALLET
|
||||||
CTransaction& tx = mapTxLockReq[ctx.txHash];
|
if(pwalletMain){
|
||||||
BOOST_FOREACH(const CTxIn& in, tx.vin){
|
if(pwalletMain->UpdatedTransaction((*i).second.txHash)){
|
||||||
if(!mapLockedInputs.count(in.prevout)){
|
nCompleteTXLocks++;
|
||||||
mapLockedInputs.insert(make_pair(in.prevout, ctx.txHash));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
// resolve conflicts
|
if(mapTxLockReq.count(ctx.txHash)){
|
||||||
|
BOOST_FOREACH(const CTxIn& in, tx.vin){
|
||||||
|
if(!mapLockedInputs.count(in.prevout)){
|
||||||
|
mapLockedInputs.insert(make_pair(in.prevout, ctx.txHash));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//if this tx lock was rejected, we need to remove the conflicting blocks
|
// resolve conflicts
|
||||||
if(mapTxLockReqRejected.count((*i).second.txHash)){
|
|
||||||
CValidationState state;
|
//if this tx lock was rejected, we need to remove the conflicting blocks
|
||||||
DisconnectBlockAndInputs(state, mapTxLockReqRejected[(*i).second.txHash]);
|
if(mapTxLockReqRejected.count((*i).second.txHash)){
|
||||||
|
CValidationState state;
|
||||||
|
DisconnectBlockAndInputs(state, mapTxLockReqRejected[(*i).second.txHash]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -350,6 +355,28 @@ bool ProcessConsensusVote(CConsensusVote& ctx)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckForConflictingLocks(CTransaction& tx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
It's possible (very unlikely though) to get 2 conflicting transaction locks approved by the network.
|
||||||
|
In that case, they will cancel each other out.
|
||||||
|
|
||||||
|
Blocks could have been rejected during this time, which is OK. After they cancel out, the client will
|
||||||
|
rescan the blocks and find they're acceptable and then take the chain with the most work.
|
||||||
|
*/
|
||||||
|
BOOST_FOREACH(const CTxIn& in, tx.vin){
|
||||||
|
if(mapLockedInputs.count(in.prevout)){
|
||||||
|
if(mapLockedInputs[in.prevout] != tx.GetHash()){
|
||||||
|
LogPrintf("InstantX::CheckForConflictingLocks - found two complete conflicting locks - removing both. %s %s", tx.GetHash().ToString().c_str(), mapLockedInputs[in.prevout].ToString().c_str());
|
||||||
|
if(mapTxLocks.count(tx.GetHash())) mapTxLocks[tx.GetHash()].nExpiration = GetTime();
|
||||||
|
if(mapTxLocks.count(mapLockedInputs[in.prevout])) mapTxLocks[mapLockedInputs[in.prevout]].nExpiration = GetTime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t GetAverageVoteTime()
|
int64_t GetAverageVoteTime()
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,9 @@ int64_t CreateNewLock(CTransaction tx);
|
|||||||
|
|
||||||
bool IsIXTXValid(const CTransaction& txCollateral);
|
bool IsIXTXValid(const CTransaction& txCollateral);
|
||||||
|
|
||||||
|
// if two conflicting locks are approved by the network, they will cancel out
|
||||||
|
bool CheckForConflictingLocks(CTransaction& tx);
|
||||||
|
|
||||||
void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
||||||
|
|
||||||
//check if we need to vote on this transaction
|
//check if we need to vote on this transaction
|
||||||
|
@ -2823,11 +2823,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
|||||||
|
|
||||||
|
|
||||||
// ----------- instantX transaction scanning -----------
|
// ----------- instantX transaction scanning -----------
|
||||||
/*
|
|
||||||
block-level scanning is working below, but we need a blockchain
|
|
||||||
based management system for storing the active masternodes. Otherwise
|
|
||||||
small inconsistances can lead to forks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
BOOST_FOREACH(const CTransaction& tx, block.vtx){
|
BOOST_FOREACH(const CTransaction& tx, block.vtx){
|
||||||
if (!tx.IsCoinBase()){
|
if (!tx.IsCoinBase()){
|
||||||
|
Loading…
Reference in New Issue
Block a user