[Fee logic] Don't count txins for priority to encourage sweeping.

This changes the priority calculation to not include the size of per-txin
 data including up to 110 bytes of scriptsig so that transactions which
 sweep up extra UTXO don't lose priority relative to ones that don't.

I'd toyed with some other variations, but it seems like any formulation
 which results in an incentive stronger than making them not count will
 sometimes create incentives to add extra outputs so that you have
 extra inputs to consume later.  The maximum credit is limited so that
 users don't lose the disincentive to stuff random data in their
 transactions, the limit of 110 is based on the size of a P2SH
 redemption with a compressed public key.

This shouldn't need a staged deployment because the priority is not
 used as a relay criteria, only a mining criteria.
This commit is contained in:
Gregory Maxwell 2013-08-28 02:15:39 -07:00
parent bb7d0fc12f
commit d6eb259953
2 changed files with 23 additions and 3 deletions

View File

@ -242,9 +242,21 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
} }
if (fMissingInputs) continue; if (fMissingInputs) continue;
// Priority is sum(valuein * age) / txsize // Priority is sum(valuein * age) / modified_txsize
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
dPriority /= nTxSize; unsigned int nTxSizeMod = nTxSize;
// In order to avoid disincentivizing cleaning up the UTXO set we don't count
// the constant overhead for each txin and up to 110 bytes of scriptSig (which
// is enough to cover a compressed pubkey p2sh redemption) for priority.
// Providing any more cleanup incentive than making additional inputs free would
// risk encouraging people to create junk outputs to redeem later.
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
unsigned int offset = 41U + min(110U, (unsigned int)txin.scriptSig.size());
if (nTxSizeMod > offset)
nTxSizeMod -= offset;
}
dPriority /= nTxSizeMod;
// This is a more accurate fee-per-kilobyte than is used by the client code, because the // This is a more accurate fee-per-kilobyte than is used by the client code, because the
// client code rounds up the size to the nearest 1K. That's good, because it gives an // client code rounds up the size to the nearest 1K. That's good, because it gives an

View File

@ -1300,7 +1300,15 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend,
strFailReason = _("Transaction too large"); strFailReason = _("Transaction too large");
return false; return false;
} }
dPriority /= nBytes; unsigned int nTxSizeMod = nBytes;
// See miner.c's dPriority logic for the matching network-node side code.
BOOST_FOREACH(const CTxIn& txin, (*(CTransaction*)&wtxNew).vin)
{
unsigned int offset = 41U + min(110U, (unsigned int)txin.scriptSig.size());
if (nTxSizeMod > offset)
nTxSizeMod -= offset;
}
dPriority /= nTxSizeMod;
// Check that enough fee is included // Check that enough fee is included
int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);