Merge pull request #746 from UdjinM6/refactorixdstx
Refactor IX/DSTX messages handling
This commit is contained in:
commit
dee72ad0cd
@ -51,13 +51,10 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
|
|||||||
CInv inv(MSG_TXLOCK_REQUEST, tx.GetHash());
|
CInv inv(MSG_TXLOCK_REQUEST, tx.GetHash());
|
||||||
pfrom->AddInventoryKnown(inv);
|
pfrom->AddInventoryKnown(inv);
|
||||||
|
|
||||||
if(mapTxLockReq.count(tx.GetHash()) || mapTxLockReqRejected.count(tx.GetHash())){
|
// have we seen it already?
|
||||||
return;
|
if(mapTxLockReq.count(inv.hash) || mapTxLockReqRejected.count(inv.hash)) return;
|
||||||
}
|
// is it a valid one?
|
||||||
|
if(!IsIXTXValid(tx)) return;
|
||||||
if(!IsIXTXValid(tx)){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxOut o, tx.vout){
|
BOOST_FOREACH(const CTxOut o, tx.vout){
|
||||||
// IX supports normal scripts and unspendable scripts (used in DS collateral and Budget collateral).
|
// IX supports normal scripts and unspendable scripts (used in DS collateral and Budget collateral).
|
||||||
@ -110,19 +107,13 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolve conflicts
|
// resolve conflicts
|
||||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(tx.GetHash());
|
if (IsLockedIXTransaction(tx.GetHash()) && !CheckForConflictingLocks(tx)){
|
||||||
if (i != mapTxLocks.end()){
|
|
||||||
//we only care if we have a complete tx lock
|
|
||||||
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
|
||||||
if(!CheckForConflictingLocks(tx)){
|
|
||||||
LogPrintf("ProcessMessageInstantX::ix - Found Existing Complete IX Lock\n");
|
LogPrintf("ProcessMessageInstantX::ix - Found Existing Complete IX Lock\n");
|
||||||
|
|
||||||
//reprocess the last 15 blocks
|
//reprocess the last 15 blocks
|
||||||
ReprocessBlocks(15);
|
ReprocessBlocks(15);
|
||||||
mapTxLockReq.insert(make_pair(tx.GetHash(), tx));
|
mapTxLockReq.insert(make_pair(tx.GetHash(), tx));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -173,7 +164,11 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
|
|||||||
|
|
||||||
bool IsIXTXValid(const CTransaction& txCollateral){
|
bool IsIXTXValid(const CTransaction& txCollateral){
|
||||||
if(txCollateral.vout.size() < 1) return false;
|
if(txCollateral.vout.size() < 1) return false;
|
||||||
if(txCollateral.nLockTime != 0) return false;
|
|
||||||
|
if(!CheckFinalTx(txCollateral)) {
|
||||||
|
LogPrint("instantx", "IsIXTXValid - Transaction is not final - %s\n", txCollateral.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t nValueIn = 0;
|
int64_t nValueIn = 0;
|
||||||
int64_t nValueOut = 0;
|
int64_t nValueOut = 0;
|
||||||
@ -360,17 +355,19 @@ bool ProcessConsensusVote(CNode* pnode, CConsensusVote& ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogPrint("instantx", "InstantX::ProcessConsensusVote - Transaction Lock Votes %d - %s !\n", (*i).second.CountSignatures(), ctx.GetHash().ToString());
|
int nSignatures = (*i).second.CountSignatures();
|
||||||
|
LogPrint("instantx", "InstantX::ProcessConsensusVote - Transaction Lock Votes %d - %s !\n", nSignatures, ctx.GetHash().ToString());
|
||||||
|
|
||||||
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
|
if(nSignatures >= INSTANTX_SIGNATURES_REQUIRED){
|
||||||
LogPrint("instantx", "InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s !\n", (*i).second.GetHash().ToString());
|
LogPrint("instantx", "InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s !\n", ctx.txHash.ToString());
|
||||||
|
|
||||||
CTransaction& tx = mapTxLockReq[ctx.txHash];
|
CTransaction& tx = mapTxLockReq[ctx.txHash];
|
||||||
if(!CheckForConflictingLocks(tx)){
|
if(!CheckForConflictingLocks(tx)){
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if(pwalletMain){
|
if(pwalletMain){
|
||||||
if(pwalletMain->UpdatedTransaction((*i).second.txHash)){
|
if(pwalletMain->UpdatedTransaction(ctx.txHash)){
|
||||||
|
// bumping this to update UI
|
||||||
nCompleteTXLocks++;
|
nCompleteTXLocks++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,7 +384,7 @@ bool ProcessConsensusVote(CNode* pnode, CConsensusVote& ctx)
|
|||||||
// resolve conflicts
|
// resolve conflicts
|
||||||
|
|
||||||
//if this tx lock was rejected, we need to remove the conflicting blocks
|
//if this tx lock was rejected, we need to remove the conflicting blocks
|
||||||
if(mapTxLockReqRejected.count((*i).second.txHash)){
|
if(mapTxLockReqRejected.count(ctx.txHash)){
|
||||||
//reprocess the last 15 blocks
|
//reprocess the last 15 blocks
|
||||||
ReprocessBlocks(15);
|
ReprocessBlocks(15);
|
||||||
}
|
}
|
||||||
@ -466,6 +463,37 @@ void CleanTransactionLocksList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsLockedIXTransaction(uint256 txHash) {
|
||||||
|
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(txHash);
|
||||||
|
return i != mapTxLocks.end() && (*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTransactionLockSignatures(uint256 txHash)
|
||||||
|
{
|
||||||
|
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound) return -2;
|
||||||
|
if(!IsSporkActive(SPORK_2_INSTANTX)) return -3;
|
||||||
|
if(!fEnableInstantX) return -1;
|
||||||
|
|
||||||
|
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(txHash);
|
||||||
|
if (i != mapTxLocks.end()){
|
||||||
|
return (*i).second.CountSignatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsTransactionLockTimedOut(uint256 txHash)
|
||||||
|
{
|
||||||
|
if(!fEnableInstantX) return 0;
|
||||||
|
|
||||||
|
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(txHash);
|
||||||
|
if (i != mapTxLocks.end()){
|
||||||
|
return GetTime() > (*i).second.nTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint256 CConsensusVote::GetHash() const
|
uint256 CConsensusVote::GetHash() const
|
||||||
{
|
{
|
||||||
return ArithToUint256(UintToArith256(vinMasternode.prevout.hash) + vinMasternode.prevout.n + UintToArith256(txHash));
|
return ArithToUint256(UintToArith256(vinMasternode.prevout.hash) + vinMasternode.prevout.n + UintToArith256(txHash));
|
||||||
|
@ -37,7 +37,6 @@ static const int MIN_INSTANTX_PROTO_VERSION = 70103;
|
|||||||
extern map<uint256, CTransaction> mapTxLockReq;
|
extern map<uint256, CTransaction> mapTxLockReq;
|
||||||
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
||||||
extern map<uint256, CConsensusVote> mapTxLockVote;
|
extern map<uint256, CConsensusVote> mapTxLockVote;
|
||||||
extern map<uint256, CTransactionLock> mapTxLocks;
|
|
||||||
extern std::map<COutPoint, uint256> mapLockedInputs;
|
extern std::map<COutPoint, uint256> mapLockedInputs;
|
||||||
extern int nCompleteTXLocks;
|
extern int nCompleteTXLocks;
|
||||||
|
|
||||||
@ -60,6 +59,15 @@ bool ProcessConsensusVote(CNode *pnode, CConsensusVote& ctx);
|
|||||||
// keep transaction locks in memory for an hour
|
// keep transaction locks in memory for an hour
|
||||||
void CleanTransactionLocksList();
|
void CleanTransactionLocksList();
|
||||||
|
|
||||||
|
// verify if transaction is currently locked
|
||||||
|
bool IsLockedIXTransaction(uint256 txHash);
|
||||||
|
|
||||||
|
// get the actual uber og accepted lock signatures
|
||||||
|
int GetTransactionLockSignatures(uint256 txHash);
|
||||||
|
|
||||||
|
// verify if transaction lock timed out
|
||||||
|
bool IsTransactionLockTimedOut(uint256 txHash);
|
||||||
|
|
||||||
int64_t GetAverageVoteTime();
|
int64_t GetAverageVoteTime();
|
||||||
|
|
||||||
class CConsensusVote
|
class CConsensusVote
|
||||||
|
94
src/main.cpp
94
src/main.cpp
@ -770,34 +770,19 @@ int GetInputAge(CTxIn& vin)
|
|||||||
|
|
||||||
int GetInputAgeIX(uint256 nTXHash, CTxIn& vin)
|
int GetInputAgeIX(uint256 nTXHash, CTxIn& vin)
|
||||||
{
|
{
|
||||||
int sigs = 0;
|
|
||||||
int nResult = GetInputAge(vin);
|
int nResult = GetInputAge(vin);
|
||||||
if(nResult < 0) nResult = 0;
|
if(nResult < 0) return -1;
|
||||||
|
|
||||||
if (nResult < 6){
|
if (nResult < 6 && IsLockedIXTransaction(nTXHash))
|
||||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(nTXHash);
|
|
||||||
if (i != mapTxLocks.end()){
|
|
||||||
sigs = (*i).second.CountSignatures();
|
|
||||||
}
|
|
||||||
if(sigs >= INSTANTX_SIGNATURES_REQUIRED){
|
|
||||||
return nInstantXDepth + nResult;
|
return nInstantXDepth + nResult;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return nResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetIXConfirmations(uint256 nTXHash)
|
int GetIXConfirmations(uint256 nTXHash)
|
||||||
{
|
{
|
||||||
int sigs = 0;
|
if (IsLockedIXTransaction(nTXHash))
|
||||||
|
|
||||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(nTXHash);
|
|
||||||
if (i != mapTxLocks.end()){
|
|
||||||
sigs = (*i).second.CountSignatures();
|
|
||||||
}
|
|
||||||
if(sigs >= INSTANTX_SIGNATURES_REQUIRED){
|
|
||||||
return nInstantXDepth;
|
return nInstantXDepth;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4394,17 +4379,9 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||||||
mapOrphanTransactions.count(inv.hash) ||
|
mapOrphanTransactions.count(inv.hash) ||
|
||||||
pcoinsTip->HaveCoins(inv.hash);
|
pcoinsTip->HaveCoins(inv.hash);
|
||||||
}
|
}
|
||||||
case MSG_DSTX:
|
|
||||||
return mapDarksendBroadcastTxes.count(inv.hash);
|
|
||||||
case MSG_BLOCK:
|
case MSG_BLOCK:
|
||||||
return mapBlockIndex.count(inv.hash);
|
return mapBlockIndex.count(inv.hash);
|
||||||
case MSG_TXLOCK_REQUEST:
|
|
||||||
return mapTxLockReq.count(inv.hash) ||
|
|
||||||
mapTxLockReqRejected.count(inv.hash);
|
|
||||||
case MSG_TXLOCK_VOTE:
|
|
||||||
return mapTxLockVote.count(inv.hash);
|
|
||||||
case MSG_SPORK:
|
|
||||||
return mapSporks.count(inv.hash);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Dash Related Inventory Messages
|
Dash Related Inventory Messages
|
||||||
@ -4415,44 +4392,38 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||||||
We're going to be asking many nodes upfront for the full inventory list, so we'll get duplicates of these.
|
We're going to be asking many nodes upfront for the full inventory list, so we'll get duplicates of these.
|
||||||
We want to only update the time on new hits, so that we can time out appropriately if needed.
|
We want to only update the time on new hits, so that we can time out appropriately if needed.
|
||||||
*/
|
*/
|
||||||
|
case MSG_TXLOCK_REQUEST:
|
||||||
|
return mapTxLockReq.count(inv.hash) || mapTxLockReqRejected.count(inv.hash);
|
||||||
|
|
||||||
|
case MSG_TXLOCK_VOTE:
|
||||||
|
return mapTxLockVote.count(inv.hash);
|
||||||
|
|
||||||
|
case MSG_SPORK:
|
||||||
|
return mapSporks.count(inv.hash);
|
||||||
|
|
||||||
case MSG_MASTERNODE_WINNER:
|
case MSG_MASTERNODE_WINNER:
|
||||||
if(mnpayments.mapMasternodePayeeVotes.count(inv.hash)) {
|
return mnpayments.mapMasternodePayeeVotes.count(inv.hash);
|
||||||
//masternodeSync.AddedMasternodeWinner(inv.hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MSG_BUDGET_VOTE:
|
case MSG_BUDGET_VOTE:
|
||||||
if(budget.mapSeenMasternodeBudgetVotes.count(inv.hash)) {
|
return budget.mapSeenMasternodeBudgetVotes.count(inv.hash);
|
||||||
//masternodeSync.AddedBudgetItem(inv.hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MSG_BUDGET_PROPOSAL:
|
case MSG_BUDGET_PROPOSAL:
|
||||||
if(budget.mapSeenMasternodeBudgetProposals.count(inv.hash)) {
|
return budget.mapSeenMasternodeBudgetProposals.count(inv.hash);
|
||||||
//masternodeSync.AddedBudgetItem(inv.hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MSG_BUDGET_FINALIZED_VOTE:
|
|
||||||
if(budget.mapSeenFinalizedBudgetVotes.count(inv.hash)) {
|
|
||||||
//masternodeSync.AddedBudgetItem(inv.hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MSG_BUDGET_FINALIZED:
|
case MSG_BUDGET_FINALIZED:
|
||||||
if(budget.mapSeenFinalizedBudgets.count(inv.hash)) {
|
return budget.mapSeenFinalizedBudgets.count(inv.hash);
|
||||||
//masternodeSync.AddedBudgetItem(inv.hash);
|
|
||||||
return true;
|
case MSG_BUDGET_FINALIZED_VOTE:
|
||||||
}
|
return budget.mapSeenFinalizedBudgetVotes.count(inv.hash);
|
||||||
return false;
|
|
||||||
case MSG_MASTERNODE_ANNOUNCE:
|
case MSG_MASTERNODE_ANNOUNCE:
|
||||||
if(mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)) {
|
return mnodeman.mapSeenMasternodeBroadcast.count(inv.hash);
|
||||||
//masternodeSync.AddedMasternodeList(inv.hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MSG_MASTERNODE_PING:
|
case MSG_MASTERNODE_PING:
|
||||||
return mnodeman.mapSeenMasternodePing.count(inv.hash);
|
return mnodeman.mapSeenMasternodePing.count(inv.hash);
|
||||||
|
|
||||||
|
case MSG_DSTX:
|
||||||
|
return mapDarksendBroadcastTxes.count(inv.hash);
|
||||||
}
|
}
|
||||||
// Don't know what it is, just say we already got one
|
// Don't know what it is, just say we already got one
|
||||||
return true;
|
return true;
|
||||||
@ -5319,11 +5290,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strCommand == NetMsgType::DSTX){
|
|
||||||
CInv inv(MSG_DSTX, tx.GetHash());
|
|
||||||
RelayInv(inv);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nDoS = 0;
|
int nDoS = 0;
|
||||||
if (state.IsInvalid(nDoS))
|
if (state.IsInvalid(nDoS))
|
||||||
{
|
{
|
||||||
|
20
src/net.cpp
20
src/net.cpp
@ -20,6 +20,7 @@
|
|||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "darksend.h"
|
#include "darksend.h"
|
||||||
|
#include "instantx.h"
|
||||||
#include "wallet/wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
|
||||||
@ -2075,7 +2076,9 @@ void RelayTransaction(const CTransaction& tx)
|
|||||||
|
|
||||||
void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
||||||
{
|
{
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
int nInv = mapDarksendBroadcastTxes.count(tx.GetHash()) ? MSG_DSTX :
|
||||||
|
(mapTxLockReq.count(tx.GetHash()) ? MSG_TXLOCK_REQUEST : MSG_TX);
|
||||||
|
CInv inv(nInv, tx.GetHash());
|
||||||
{
|
{
|
||||||
LOCK(cs_mapRelay);
|
LOCK(cs_mapRelay);
|
||||||
// Expire old relay messages
|
// Expire old relay messages
|
||||||
@ -2104,21 +2107,6 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RelayTransactionLockReq(const CTransaction& tx, bool relayToAll)
|
|
||||||
{
|
|
||||||
CInv inv(MSG_TXLOCK_REQUEST, tx.GetHash());
|
|
||||||
|
|
||||||
//broadcast the new lock
|
|
||||||
LOCK(cs_vNodes);
|
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
|
||||||
{
|
|
||||||
if(!relayToAll && !pnode->fRelayTxes)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pnode->PushMessage(NetMsgType::IX, tx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RelayInv(CInv &inv, const int minProtoVersion) {
|
void RelayInv(CInv &inv, const int minProtoVersion) {
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
|
@ -850,7 +850,6 @@ public:
|
|||||||
class CTransaction;
|
class CTransaction;
|
||||||
void RelayTransaction(const CTransaction& tx);
|
void RelayTransaction(const CTransaction& tx);
|
||||||
void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
|
void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
|
||||||
void RelayTransactionLockReq(const CTransaction& tx, bool relayToAll=false);
|
|
||||||
void RelayInv(CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
|
void RelayInv(CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
|
||||||
|
|
||||||
/** Access to the (IP) address database (peers.dat) */
|
/** Access to the (IP) address database (peers.dat) */
|
||||||
|
@ -34,7 +34,7 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int signatures = wtx.GetTransactionLockSignatures();
|
int signatures = GetTransactionLockSignatures(wtx.GetHash());
|
||||||
QString strUsingIX = "";
|
QString strUsingIX = "";
|
||||||
if(signatures >= 0){
|
if(signatures >= 0){
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
|
|||||||
else
|
else
|
||||||
return tr("%1 confirmations (verified via instantx)").arg(nDepth);
|
return tr("%1 confirmations (verified via instantx)").arg(nDepth);
|
||||||
} else {
|
} else {
|
||||||
if(!wtx.IsTransactionLockTimedOut()){
|
if(!IsTransactionLockTimedOut(wtx.GetHash())){
|
||||||
int nDepth = wtx.GetDepthInMainChain();
|
int nDepth = wtx.GetDepthInMainChain();
|
||||||
if (nDepth < 0)
|
if (nDepth < 0)
|
||||||
return tr("conflicted");
|
return tr("conflicted");
|
||||||
|
@ -1485,10 +1485,8 @@ bool CWalletTx::RelayWalletTransaction(std::string strCommand)
|
|||||||
if(strCommand == NetMsgType::IX){
|
if(strCommand == NetMsgType::IX){
|
||||||
mapTxLockReq.insert(make_pair(hash, (CTransaction)*this));
|
mapTxLockReq.insert(make_pair(hash, (CTransaction)*this));
|
||||||
CreateNewLock(((CTransaction)*this));
|
CreateNewLock(((CTransaction)*this));
|
||||||
RelayTransactionLockReq((CTransaction)*this, true);
|
|
||||||
} else {
|
|
||||||
RelayTransaction((CTransaction)*this);
|
|
||||||
}
|
}
|
||||||
|
RelayTransaction((CTransaction)*this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2845,7 +2843,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
// enough, that fee sniping isn't a problem yet, but by implementing a fix
|
// enough, that fee sniping isn't a problem yet, but by implementing a fix
|
||||||
// now we ensure code won't be written that makes assumptions about
|
// now we ensure code won't be written that makes assumptions about
|
||||||
// nLockTime that preclude a fix later.
|
// nLockTime that preclude a fix later.
|
||||||
txNew.nLockTime = chainActive.Height();
|
|
||||||
|
// FIXME: "compatibility mode" for 12.0 IX, make it "txNew.nLockTime = chainActive.Height();" again in 12.2
|
||||||
|
txNew.nLockTime = useIX ? 0 : chainActive.Height();
|
||||||
|
|
||||||
// Secondly occasionally randomly pick a nLockTime even further back, so
|
// Secondly occasionally randomly pick a nLockTime even further back, so
|
||||||
// that transactions that are delayed after signing for whatever reason,
|
// that transactions that are delayed after signing for whatever reason,
|
||||||
@ -4055,33 +4055,33 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
|
|||||||
|
|
||||||
int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet, bool enableIX) const
|
int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet, bool enableIX) const
|
||||||
{
|
{
|
||||||
if (hashUnset())
|
int nResult;
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
if (hashUnset())
|
||||||
|
nResult = 0;
|
||||||
|
else {
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
// Find the block it claims to be in
|
// Find the block it claims to be in
|
||||||
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
|
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
|
||||||
if (mi == mapBlockIndex.end())
|
if (mi == mapBlockIndex.end())
|
||||||
return 0;
|
nResult = 0;
|
||||||
|
else {
|
||||||
CBlockIndex* pindex = (*mi).second;
|
CBlockIndex* pindex = (*mi).second;
|
||||||
if (!pindex || !chainActive.Contains(pindex))
|
if (!pindex || !chainActive.Contains(pindex))
|
||||||
return 0;
|
nResult = 0;
|
||||||
|
else {
|
||||||
pindexRet = pindex;
|
pindexRet = pindex;
|
||||||
int nResult = ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
|
nResult = ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
|
||||||
|
|
||||||
if (nResult == 0 && !mempool.exists(GetHash()))
|
if (nResult == 0 && !mempool.exists(GetHash()))
|
||||||
return -1; // Not in chain, not in mempool
|
return -1; // Not in chain, not in mempool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(enableIX){
|
if(enableIX && nResult < 6 && IsLockedIXTransaction(GetHash()))
|
||||||
if (nResult < 6){
|
|
||||||
int signatures = GetTransactionLockSignatures();
|
|
||||||
if(signatures >= INSTANTX_SIGNATURES_REQUIRED){
|
|
||||||
return nInstantXDepth + nResult;
|
return nInstantXDepth + nResult;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nResult;
|
return nResult;
|
||||||
}
|
}
|
||||||
@ -4099,30 +4099,3 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee);
|
return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMerkleTx::GetTransactionLockSignatures() const
|
|
||||||
{
|
|
||||||
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound) return -2;
|
|
||||||
if(!IsSporkActive(SPORK_2_INSTANTX)) return -3;
|
|
||||||
if(!fEnableInstantX) return -1;
|
|
||||||
|
|
||||||
//compile consessus vote
|
|
||||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(GetHash());
|
|
||||||
if (i != mapTxLocks.end()){
|
|
||||||
return (*i).second.CountSignatures();
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
bool CMerkleTx::IsTransactionLockTimedOut() const
|
|
||||||
{
|
|
||||||
if(!fEnableInstantX) return 0;
|
|
||||||
|
|
||||||
//compile consessus vote
|
|
||||||
std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(GetHash());
|
|
||||||
if (i != mapTxLocks.end()){
|
|
||||||
return GetTime() > (*i).second.nTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -228,8 +228,6 @@ public:
|
|||||||
int GetDepthInMainChain(bool enableIX = true) const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet, enableIX); }
|
int GetDepthInMainChain(bool enableIX = true) const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet, enableIX); }
|
||||||
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
|
bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; }
|
||||||
int GetBlocksToMaturity() const;
|
int GetBlocksToMaturity() const;
|
||||||
int GetTransactionLockSignatures() const;
|
|
||||||
bool IsTransactionLockTimedOut() const;
|
|
||||||
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
|
bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
|
||||||
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); }
|
||||||
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
bool isAbandoned() const { return (hashBlock == ABANDON_HASH); }
|
||||||
|
Loading…
Reference in New Issue
Block a user