Improved masternode payments

This commit is contained in:
Evan Duffield 2015-02-03 10:17:30 -07:00
parent ffec62e8ba
commit feb9a1e922
4 changed files with 72 additions and 81 deletions

View File

@ -84,7 +84,7 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
return;
} else {
mapTxLockReqRejected.insert(make_pair(inv.hash, tx));
mapTxLockReqRejected.insert(make_pair(tx.GetHash(), tx));
// can we get the conflicting transaction as proof?
@ -96,6 +96,31 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
tx.GetHash().ToString().c_str()
);
// resolve conflicts
/*std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(tx.GetHash());
if (i != mapTxLocks.end()){
if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
LogPrintf("ProcessMessageInstantX::txlreq - Found IX lock\n");
uint256 txHash = (*i).second.txHash;
CValidationState state;
bool fMissingInputs = false;
DisconnectBlockAndInputs(state, mapTxLockReqRejected[txHash]);
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
{
LogPrintf("ProcessMessageInstantX::txlreq - Transaction Lock Request : accepted (resolved) %s\n",
pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str(),
tx.GetHash().ToString().c_str()
);
} else {
LogPrintf("ERROR: InstantX::ProcessConsensusVote - Transaction Lock Request : rejected (failed to resolve) %s\n",
tx.GetHash().ToString().c_str()
);
}
}
}*/
//record prevout, increment the amount of times seen. Ban if over 100
return;
@ -226,6 +251,27 @@ bool ProcessConsensusVote(CConsensusVote& ctx)
if(pwalletMain->UpdatedTransaction((*i).second.txHash)){
nCompleteTXLocks++;
}
// resolve conflicts
/*
//if this tx lock was rejected, we need to remove the conflicting blocks
if(mapTxLockReqRejected.count((*i).second.txHash)){
CValidationState state;
bool fMissingInputs = false;
DisconnectBlockAndInputs(state, mapTxLockReqRejected[(*i).second.txHash]);
if (AcceptToMemoryPool(mempool, state, mapTxLockReqRejected[(*i).second.txHash], true, &fMissingInputs))
{
LogPrintf("ProcessMessageInstantX::txlreq - Transaction Lock Request : accepted (resolved) %s\n",
mapTxLockReqRejected[(*i).second.txHash].GetHash().ToString().c_str()
);
} else {
LogPrintf("ERROR: InstantX::ProcessConsensusVote - Transaction Lock Request : rejected (failed to resolve) %s\n",
mapTxLockReqRejected[(*i).second.txHash].GetHash().ToString().c_str()
);
}
}*/
}
return true;
}

View File

@ -2116,7 +2116,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
*/
bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
{
/* // All modifications to the coin state will be done in this cache.
/*
// All modifications to the coin state will be done in this cache.
// Only when all have succeeded, we push it to pcoinsTip.
CCoinsViewCache view(*pcoinsTip, true);
@ -2127,7 +2128,9 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
bool foundConflictingTx = false;
//remove anything conflicting in the memory pool
mempool.removeConflicts(txLock);
list<CTransaction> txConflicted;
mempool.removeConflicts(txLock, txConflicted);
// List of what to disconnect (typically nothing)
vector<CBlockIndex*> vDisconnect;
@ -2137,7 +2140,7 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
pindexNew = BlockReading->pprev; //new best block
CBlock block;
if (!block.ReadFromDisk(BlockReading))
if (!ReadBlockFromDisk(block, BlockReading))
return state.Abort(_("Failed to read block"));
// Queue memory transactions to resurrect.
@ -2163,7 +2166,7 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
}
if (vDisconnect.size() > 0) {
LogPrintf("REORGANIZE: Disconnect Conflicting Blocks %"PRIszu" blocks; %s..\n", vDisconnect.size(), pindexNew->GetBlockHash().ToString().c_str());
LogPrintf("REORGANIZE: Disconnect Conflicting Blocks %lli blocks; %s..\n", vDisconnect.size(), pindexNew->GetBlockHash().ToString().c_str());
BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) {
LogPrintf(" -- disconnect %s\n", pindex->GetBlockHash().ToString().c_str());
}
@ -2173,10 +2176,10 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
vector<CTransaction> vResurrect;
BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) {
CBlock block;
if (!block.ReadFromDisk(pindex))
if (!ReadBlockFromDisk(block, pindex))
return state.Abort(_("Failed to read block"));
int64 nStart = GetTimeMicros();
if (!block.DisconnectBlock(state, pindex, view))
int64_t nStart = GetTimeMicros();
if (!DisconnectBlock(block, state, pindex, view))
return error("DisconnectBlockAndInputs/SetBestBlock() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().c_str());
if (fBenchmark)
LogPrintf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
@ -2198,21 +2201,7 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
}
// Make sure it's successfully written to disk before changing memory structure
bool fIsInitialDownload = IsInitialBlockDownload();
if (!fIsInitialDownload || pcoinsTip->GetCacheSize() > nCoinCacheSize) {
// Typical CCoins structures on disk are around 100 bytes in size.
// Pushing a new one to the database can cause it to be written
// twice (once in the log, and once in the tables). This is already
// an overestimation, as most will delete an existing entry or
// overwrite one. Still, use a conservative safety factor of 2.
if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize()))
return state.Error();
FlushBlockFile();
pblocktree->Sync();
if (!pcoinsTip->Flush())
return state.Abort(_("Failed to write to coin database"));
}
mempool.check(pcoinsTip);
// At this point, all changes have been done to the database.
// Proceed by updating the memory structures.
@ -2226,11 +2215,12 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
BOOST_FOREACH(CTransaction& tx, vResurrect) {
// ignore validation errors in resurrected transactions
CValidationState stateDummy;
if (!tx.AcceptToMemoryPool(stateDummy, true, false))
if (!tx.AcceptToMemoryPool(mempool, stateDummy, tx, true, false))
mempool.remove(tx, true);
}
// Update best block in wallet (so we can detect restored wallets)
if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0))
{
const CBlockLocator locator(pindexNew);
@ -2275,8 +2265,8 @@ bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
boost::replace_all(strCmd, "%s", hashBestChain.GetHex());
boost::thread t(runCommand, strCmd); // thread runs free
}
*/
return true;
*/ return true;
}
void static FlushBlockFile(bool fFinalize = false)

View File

@ -18,8 +18,6 @@ map<uint256, int> mapSeenMasternodeScanningErrors;
std::map<CNetAddr, int64_t> askedForMasternodeList;
// which masternodes we've asked for
std::map<COutPoint, int64_t> askedForMasternodeListEntry;
// which masternodes we've asked for
std::map<int, CScript> cacheBlockPayee;
// manage the masternode connections
void ProcessMasternodeConnections(){
@ -361,22 +359,6 @@ void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream
if(masternodePayments.AddWinningMasternode(winner)){
masternodePayments.Relay(winner);
}
if(chainActive.Tip()){
//cache payments
int success = 0;
int fail = 0;
for(int nBlockHeight = chainActive.Tip()->nHeight; nBlockHeight < chainActive.Tip()->nHeight+10; nBlockHeight++){
CScript payee;
if(masternodePayments.GetBlockPayee(nBlockHeight, payee)){
success++;
} else {
fail++;
}
}
LogPrintf("mnw - cached block payees - success %d fail %d\n", success, fail);
}
}
}
@ -663,29 +645,10 @@ uint64_t CMasternodePayments::CalculateScore(uint256 blockHash, CTxIn& vin)
bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
{
// if it's cached, use it
if(cacheBlockPayee.count(nBlockHeight)){
payee = cacheBlockPayee[nBlockHeight];
return true;
}
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.nBlockHeight == nBlockHeight) {
CTransaction tx;
uint256 hash;
if(GetTransaction(winner.vin.prevout.hash, tx, hash, true)){
BOOST_FOREACH(CTxOut out, tx.vout){
if(out.nValue == 1000*COIN){
payee = out.scriptPubKey;
cacheBlockPayee.insert(make_pair(nBlockHeight, payee));
return true;
}
}
}
return false;
payee = winner.payee;
return true;
}
}
@ -720,6 +683,7 @@ bool CMasternodePayments::AddWinningMasternode(CMasternodePaymentWinner& winnerI
if(winner.score < winnerIn.score){
winner.score = winnerIn.score;
winner.vin = winnerIn.vin;
winner.payee = winnerIn.payee;
winner.vchSig = winnerIn.vchSig;
return true;
}
@ -751,20 +715,6 @@ void CMasternodePayments::CleanPaymentList()
}
}
int CMasternodePayments::LastPayment(CMasterNode& mn)
{
if(chainActive.Tip() == NULL) return 0;
int ret = mn.GetMasternodeInputAge();
BOOST_FOREACH(CMasternodePaymentWinner& winner, vWinning){
if(winner.vin == mn.vin && chainActive.Tip()->nHeight - winner.nBlockHeight < ret)
ret = chainActive.Tip()->nHeight - winner.nBlockHeight;
}
return ret;
}
bool CMasternodePayments::ProcessBlock(int nBlockHeight)
{
if(!enabled) return false;
@ -797,6 +747,8 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight)
winner.score = 0;
winner.nBlockHeight = nBlockHeight;
winner.vin = mn.vin;
winner.payee.SetDestination(mn.pubkey.GetID());
break;
}

View File

@ -158,6 +158,7 @@ class CMasternodePaymentWinner
public:
int nBlockHeight;
CTxIn vin;
CScript payee;
std::vector<unsigned char> vchSig;
uint64_t score;
@ -165,6 +166,7 @@ public:
nBlockHeight = 0;
score = 0;
vin = CTxIn();
payee = CScript();
}
uint256 GetHash(){
@ -176,8 +178,9 @@ public:
IMPLEMENT_SERIALIZE(
READWRITE(nBlockHeight);
READWRITE(score);
READWRITE(payee);
READWRITE(vin);
READWRITE(score);
READWRITE(vchSig);
)
};