Yes, both fairbrix and tenebrix are susceptible to the same transaction spams. I do not plan to update fairbrix with the fixes. If anyone wants to keep fairbrix alive, feel free to take over.
I won't be taking over, but since I have been digging around the litecoin code recently I decided to see how hard it would be to port my changes to fairbrix. If people are really still interested in fairbrix they should put together a bounty pool to pay for future updates.
I made changes in line with what coblee did for litecoin, but modified them some to take into account the differing block times and current value of a coin. I've also put in some other changes that I think will help fairbrix resist attack in the future. All the changes I made relate to spam transactions being included or relayed by honest nodes. If an attacker controls a significant portion of the hash power (a real possibility in fairbrix) he can bypass these checks and write 1,000,000 byte blocks.
You can get the source from:
https://github.com/beecee1/Fairbrix sorry, no pre-compiled binaries.
If you like what I have done, you can donate: fVQZtuBPRdVjbNskqHLB4e75Uq64dM9vWN
Here is a description of all the changes I made (and, you have the source code so you can verify it yourself).
In main.h:
From:
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
To 125,000 bytes:
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/8;
Why: reduces the size of a block that an unmodified client will generate, helps protect against block-chain growth attacks
From:
static const int64 CENT = 1000000;
To:
static const int64 CENT = COIN/100;
Why: easier to read, no real change
From:
static const int64 MIN_TX_FEE = 50000;
static const int64 MIN_RELAY_TX_FEE = 10000;
To:
static const int64 MIN_TX_FEE = 1000000;
static const int64 MIN_RELAY_TX_FEE = MIN_TX_FEE;
Why: increase the minimum fee (when fees apply) to 0.01. This is less than litecoins so you that the fee isn't quite so large when you send an output that is nearly a cent. However, there is code elsewhere that will increase this fee for very small outputs.
From:
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
To:
int64 nMinFee = (1 + (int64)nBytes / 500) * nBaseFee;
Why: This makes large sized transactions cost a more than before.
From:
if (nNewBlockSize < 27000)
To:
if (nNewBlockSize < 12000)
Why: since blocks are faster than in bitcoin, reserve less space for free transactions.
From:
if (nMinFee < nBaseFee)
BOOST_FOREACH(const CTxOut& txout, vout)
if (txout.nValue < CENT)
nMinFee = nBaseFee;
To:
BOOST_FOREACH(const CTxOut& txout, vout) {
if (txout.nValue < CENT/10) { // outputs smaller than 0.0001
nMinFee += nBaseFee * 10; // fee of 1
smallTxOutCount++;
}
else if ((txout.nValue < CENT)) {
nMinFee += nBaseFee;
smallTxOutCount++;
}
}
Also add:
if(smallTxOutCount > 15)
nMinFee = MAX_MONEY;
Why: This is the core change to limit dust spam. Instead of a flat fee for small outputs charge a fee for each small output. If there are more than 15 small outputs than don't allow the transaction at all.
In main.cpp
From:
if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
To:
dFreeRelay = GetArg("-limitfreerelay", 5)*10*1000;
dPartialRelay = dFreeRelay * 0.75;
dNewFreeCount = dFreeCount + nSize;
if( !( dNewFreeCount <= dFreeRelay
|| dFreeCount < dPartialRelay
|| IsFromMe(*this)
)
)
Why: another spam attack mitigation. Don't relay more than (on average) 5000 bytes of free transactions a minute. This is roughly equivilant to 20 normal sized transactions per minute, which is far in excess of the current volume.
Add:
(nHeight == 15000 && hash != uint256("0x7c7fc755c19616fd3eb156b53dae2bbf058972e0731f3d0ee54785cc222f4bbf")))
Why: add a checkpoint lockin at block 15000
From:
bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
To:
bool fAllowFree = (nBlockSize + nTxSize < 1800 || CTransaction::AllowFree(dPriority));
Why: Since blocks are faster in Fairbrix, don't allow as many exempted free transactions. (But they are slower than Litecoin's so allow more than that).
In wallet.cpp:
From:
int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
To:
int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 500);
Why: matching a change made in main.h