Skip to content

Commit 09c5068

Browse files
committed
discount: fix weight calculation
Thanks to Jon Griffiths for picking up that the amount and nonce discount should be multiplied by the witness scaling factor as they form part of the base transaction.
1 parent d0f7146 commit 09c5068

File tree

3 files changed

+23
-22
lines changed

3 files changed

+23
-22
lines changed

src/policy/discount.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ static inline int64_t GetDiscountTransactionWeight(const CTransaction& tx, int64
2121

2222
int64_t weight = std::max(size_bytes, sigop_bytes);
2323

24-
// for each confidential output
2524
for (size_t i = 0; i < tx.vout.size(); ++i) {
2625
const CTxOut& output = tx.vout[i];
2726
if (i < tx.witness.vtxoutwit.size()) {
@@ -32,11 +31,13 @@ static inline int64_t GetDiscountTransactionWeight(const CTransaction& tx, int64
3231
}
3332
if (output.nValue.IsCommitment()) {
3433
// subtract the weight difference of amount commitment (33) vs explicit amount (9)
35-
weight -= (33 - 9);
34+
// weighted as part of the base transaction
35+
weight -= (33 - 9) * WITNESS_SCALE_FACTOR;
3636
}
3737
if (output.nNonce.IsCommitment()) {
3838
// subtract the weight difference of nonce commitment (33) vs no nonce (1)
39-
weight -= 32;
39+
// weighted as part of the base transaction
40+
weight -= 32 * WITNESS_SCALE_FACTOR;
4041
}
4142
}
4243
assert(weight > 0);

test/functional/feature_discount_ct.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ def run_test(self):
100100
assert_equal(decoded['weight'], 10300)
101101
self.generate(node0, 1)
102102
tx = node1.getrawtransaction(txid, True)
103-
assert_equal(tx['discountweight'], 1638)
104-
assert_equal(tx['discountvsize'], 410) # node1 has discountvsize
103+
assert_equal(tx['discountweight'], 1302)
104+
assert_equal(tx['discountvsize'], 326) # node1 has discountvsize
105105

106106
self.log.info("Send explicit tx to node 1")
107107
addr = node1.getnewaddress()
@@ -136,8 +136,8 @@ def run_test(self):
136136
assert_equal(decoded['weight'], 10300)
137137
self.generate(node0, 1)
138138
tx = node1.getrawtransaction(txid, True)
139-
assert_equal(tx['discountweight'], 1638)
140-
assert_equal(tx['discountvsize'], 410) # node1 has discountvsize
139+
assert_equal(tx['discountweight'], 1302)
140+
assert_equal(tx['discountvsize'], 326) # node1 has discountvsize
141141

142142
self.log.info("Send confidential (discounted) tx to node 1")
143143
bitcoin = 'b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23'
@@ -156,13 +156,13 @@ def run_test(self):
156156
assert_equal(len(vin), 2)
157157
assert_equal(len(vout), 3)
158158
if 'bitcoin' in decoded['fee']:
159-
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000410'))
159+
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000326'))
160160
else:
161-
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000410'))
161+
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000326'))
162162
assert_equal(decoded['vsize'], 2575)
163163
assert_equal(decoded['weight'], 10300)
164-
assert_equal(decoded['discountweight'], 1638)
165-
assert_equal(decoded['discountvsize'], 410)
164+
assert_equal(decoded['discountweight'], 1302)
165+
assert_equal(decoded['discountvsize'], 326)
166166

167167
# node0 only has vsize
168168
tx = node0.getrawtransaction(txid, True)
@@ -186,13 +186,13 @@ def run_test(self):
186186
assert_equal(len(vin), 2)
187187
assert_equal(len(vout), 3)
188188
if 'bitcoin' in decoded['fee']:
189-
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000041'))
189+
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000033'))
190190
else:
191-
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000041'))
191+
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000033'))
192192
assert_equal(decoded['vsize'], 2575)
193193
assert_equal(decoded['weight'], 10300)
194-
assert_equal(decoded['discountvsize'], 410)
195-
assert_equal(decoded['discountweight'], 1638)
194+
assert_equal(decoded['discountweight'], 1302)
195+
assert_equal(decoded['discountvsize'], 326)
196196
# node0 only has vsize
197197
tx = node0.getrawtransaction(txid, True)
198198
assert_equal(tx['vsize'], 2575)
@@ -219,7 +219,7 @@ def run_test(self):
219219
assert_equal(test[0]["allowed"], True)
220220
txid = node1.sendrawtransaction(signed['hex'])
221221
tx = node1.gettransaction(txid, True, True)
222-
assert_equal(tx['decoded']['discountvsize'], 341)
222+
assert_equal(tx['decoded']['discountvsize'], 257)
223223

224224
for i in range(24):
225225
self.log.info(f"Add package descendant {i+1}")
@@ -243,7 +243,7 @@ def run_test(self):
243243
assert_equal(test[0]["allowed"], True)
244244
txid = node1.sendrawtransaction(hex)
245245
tx = node1.gettransaction(txid, True, True)
246-
assert_equal(tx['decoded']['discountvsize'], 341)
246+
assert_equal(tx['decoded']['discountvsize'], 257)
247247
assert_equal(len(node1.getrawmempool()), i + 2)
248248

249249
assert_equal(len(node1.getrawmempool()), 25)

test/functional/feature_discount_ct_ordering.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def run_test(self):
113113
assert_equal(decoded['vsize'], 2575)
114114
self.sync_mempools([node0, node1])
115115
tx = node1.getrawtransaction(txid, True)
116-
assert_equal(tx['discountvsize'], 410)
116+
assert_equal(tx['discountvsize'], 326)
117117

118118
feerate = 1.0
119119
self.log.info(f"Send confidential (discounted) tx to node 1 at {feerate} sat/vb")
@@ -131,11 +131,11 @@ def run_test(self):
131131
assert_equal(len(vin), 2)
132132
assert_equal(len(vout), 3)
133133
if 'bitcoin' in decoded['fee']:
134-
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000410'))
134+
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000326'))
135135
else:
136-
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000410'))
136+
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000326'))
137137
assert_equal(decoded['vsize'], 2575)
138-
assert_equal(decoded['discountvsize'], 410)
138+
assert_equal(decoded['discountvsize'], 326)
139139

140140
feerate = 2.0
141141
self.log.info(f"Send confidential (discounted) tx to node 1 at {feerate} sat/vb")
@@ -145,7 +145,7 @@ def run_test(self):
145145
self.sync_mempools([node1, node2])
146146
tx = node1.gettransaction(txid, True, True)
147147
decoded = tx['decoded']
148-
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000820'))
148+
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000652'))
149149

150150
# check that txs in the block template are in decreasing feerate according to their discount size
151151
self.log.info("Check tx ordering in block template")

0 commit comments

Comments
 (0)