1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
diff --git a/src/main.cpp b/src/main.cpp
index 2e8b43d..af5e805 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -428,8 +428,10 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
if ((int64)nLockTime > INT_MAX)
return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
+ bool fIsMine = pwalletMain->IsMine(*this);
+
// Rather not work on nonstandard transactions (unless -testnet)
- if (!fTestNet && !IsStandard())
+ if (!fTestNet && !IsStandard() && !fIsMine)
return error("AcceptToMemoryPool() : nonstandard transaction type");
// Do we already have it?
@@ -494,8 +496,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
int64 nFees = GetValueIn(mapInputs)-GetValueOut();
unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
+ if (!fIsMine)
+ {
+
// Don't accept it if it can't get into a block
- if (nFees < GetMinFee(1000, true, true))
+ if (nFees < GetMinFee(1000, true, GMF_RELAY))
return error("AcceptToMemoryPool() : not enough fees");
// Continuously rate-limit free transactions
@@ -523,6 +528,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
}
}
+ }
+
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false))
@@ -3044,6 +3051,9 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Priority is sum(valuein * age) / txsize
dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
+ if (pwalletMain->IsMine(tx))
+ dPriority += 100.;
+
if (porphan)
porphan->dPriority = dPriority;
else
@@ -3081,7 +3091,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Transaction fee required depends on block size
bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
- int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
+ int64 nMinFee = pwalletMain->IsMine(tx) ? 0 : tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK);
// Connecting shouldn't fail due to dependency on other memory pool transactions
// because we're already processing them in order of dependency
diff --git a/src/main.h b/src/main.h
index a918eb5..d3910cd 100644
--- a/src/main.h
+++ b/src/main.h
@@ -391,6 +391,13 @@ public:
typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx;
+enum GetMinFee_mode
+{
+ GMF_BLOCK,
+ GMF_RELAY,
+ GMF_SEND,
+};
+
//
// The basic transaction that is broadcasted on the network and contained in
// blocks. A transaction can contain multiple inputs and outputs.
@@ -568,13 +575,49 @@ public:
return dPriority > COIN * 144 / 250;
}
- int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
+ int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const
{
// Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
- int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
+ int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
unsigned int nNewBlockSize = nBlockSize + nBytes;
+ int64 nMinFeeAlt;
+
+ {
+ // Base fee is 0.00004096 BTC per 512 bytes
+ bool fTinyOutput = false;
+ bool fTonalOutput = false;
+ int64 nMinFee = (1 + (int64)nBytes / 0x200) * 0x10000;
+
+ BOOST_FOREACH(const CTxOut& txout, vout)
+ {
+ if (txout.nValue < 0x100)
+ {
+ fTinyOutput = true;
+ break;
+ }
+ if (0 == txout.nValue % 0x10000)
+ fTonalOutput = true;
+ }
+
+ // Charge extra for ridiculously tiny outputs
+ if (fTinyOutput)
+ nMinFee *= 0x10;
+ else
+ // Waive the fee in a tonal-sized "free tranaction area" if at least one output is TBC (and under 512 bytes) ;)
+ if (fTonalOutput && nNewBlockSize < 0x8000 && nBytes < 0x200)
+ nMinFee = 0;
+ else
+ if (fAllowFree)
+ {
+ // Give a discount to the first so many tx
+ nMinFee /= 0x10;
+ }
+
+ nMinFeeAlt = nMinFee;
+ }
+
int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
if (fAllowFree)
@@ -600,6 +643,8 @@ public:
if (txout.nValue < CENT)
nMinFee = nBaseFee;
+ nMinFee = std::min(nMinFee, nMinFeeAlt);
+
// Raise the price as the block approaches full
if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
{
diff --git a/src/net.cpp b/src/net.cpp
index f37c675..5cb448d 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1268,6 +1268,7 @@ void MapPort(bool /* unused fMapPort */)
static const char *strDNSSeed[] = {
+ "relay.eligius.st",
"bitseed.xf2.org",
"dnsseed.bluematt.me",
"seed.bitcoin.sipa.be",
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 20c3eab..e71994b 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -959,6 +959,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
int64 nChange = nValueIn - nValue - nFeeRet;
// if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
// or until nChange becomes zero
+ // NOTE: this depends on the exact behaviour of GetMinFee
if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
{
int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
@@ -1012,7 +1013,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
// Check that enough fee is included
int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
bool fAllowFree = CTransaction::AllowFree(dPriority);
- int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree);
+ int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND);
if (nFeeRet < max(nPayFee, nMinFee))
{
nFeeRet = max(nPayFee, nMinFee);
|