mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge pull request #1366 from delta1/discountweight
discount: fix weight calculation
This commit is contained in:
commit
fbc01d56d7
4 changed files with 43 additions and 22 deletions
|
|
@ -237,11 +237,12 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
|
|||
entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion)));
|
||||
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
|
||||
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
|
||||
entry.pushKV("weight", GetTransactionWeight(tx));
|
||||
// ELEMENTS: add discountvsize
|
||||
if (Params().GetAcceptDiscountCT()) {
|
||||
entry.pushKV("discountvsize", GetDiscountVirtualTransactionSize(tx));
|
||||
entry.pushKV("discountweight", GetDiscountTransactionWeight(tx));
|
||||
}
|
||||
entry.pushKV("weight", GetTransactionWeight(tx));
|
||||
entry.pushKV("locktime", (int64_t)tx.nLockTime);
|
||||
|
||||
UniValue vin{UniValue::VARR};
|
||||
|
|
|
|||
|
|
@ -12,16 +12,15 @@
|
|||
#include <version.h>
|
||||
|
||||
/**
|
||||
* Calculate a smaller virtual size for discounted Confidential Transactions.
|
||||
* Calculate a smaller weight for discounted Confidential Transactions.
|
||||
*/
|
||||
static inline int64_t GetDiscountVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0, unsigned int bytes_per_sig_op = 0)
|
||||
static inline int64_t GetDiscountTransactionWeight(const CTransaction& tx, int64_t nSigOpCost = 0, unsigned int bytes_per_sig_op = 0)
|
||||
{
|
||||
int64_t size_bytes = ::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(tx, PROTOCOL_VERSION);
|
||||
int64_t sigop_bytes = nSigOpCost * bytes_per_sig_op;
|
||||
|
||||
int64_t weight = std::max(size_bytes, sigop_bytes);
|
||||
|
||||
// for each confidential output
|
||||
for (size_t i = 0; i < tx.vout.size(); ++i) {
|
||||
const CTxOut& output = tx.vout[i];
|
||||
if (i < tx.witness.vtxoutwit.size()) {
|
||||
|
|
@ -32,16 +31,25 @@ static inline int64_t GetDiscountVirtualTransactionSize(const CTransaction& tx,
|
|||
}
|
||||
if (output.nValue.IsCommitment()) {
|
||||
// subtract the weight difference of amount commitment (33) vs explicit amount (9)
|
||||
weight -= (33 - 9);
|
||||
// weighted as part of the base transaction
|
||||
weight -= (33 - 9) * WITNESS_SCALE_FACTOR;
|
||||
}
|
||||
if (output.nNonce.IsCommitment()) {
|
||||
// subtract the weight difference of nonce commitment (33) vs no nonce (1)
|
||||
weight -= 32;
|
||||
// weighted as part of the base transaction
|
||||
weight -= 32 * WITNESS_SCALE_FACTOR;
|
||||
}
|
||||
}
|
||||
assert(weight > 0);
|
||||
return weight;
|
||||
}
|
||||
|
||||
size_t discountvsize = (weight + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
|
||||
/**
|
||||
* Calculate a smaller virtual size for discounted Confidential Transactions.
|
||||
*/
|
||||
static inline int64_t GetDiscountVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0, unsigned int bytes_per_sig_op = 0)
|
||||
{
|
||||
size_t discountvsize = (GetDiscountTransactionWeight(tx, nSigOpCost, bytes_per_sig_op) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
|
||||
|
||||
assert(discountvsize > 0);
|
||||
return discountvsize;
|
||||
|
|
|
|||
|
|
@ -79,8 +79,10 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vout), 3)
|
||||
assert_equal(tx['fee']['bitcoin'], Decimal('-0.00000326'))
|
||||
assert_equal(decoded['vsize'], 326)
|
||||
assert_equal(decoded['weight'], 1302)
|
||||
self.generate(node0, 1)
|
||||
tx = node1.getrawtransaction(txid, True)
|
||||
assert_equal(tx['discountweight'], 1302)
|
||||
assert_equal(tx['discountvsize'], 326)
|
||||
|
||||
self.log.info("Send confidential tx to node 0")
|
||||
|
|
@ -95,9 +97,11 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vout), 3)
|
||||
assert_equal(tx['fee']['bitcoin'], Decimal('-0.00002575'))
|
||||
assert_equal(decoded['vsize'], 2575)
|
||||
assert_equal(decoded['weight'], 10300)
|
||||
self.generate(node0, 1)
|
||||
tx = node1.getrawtransaction(txid, True)
|
||||
assert_equal(tx['discountvsize'], 410) # node1 has discountvsize
|
||||
assert_equal(tx['discountweight'], 1302)
|
||||
assert_equal(tx['discountvsize'], 326) # node1 has discountvsize
|
||||
|
||||
self.log.info("Send explicit tx to node 1")
|
||||
addr = node1.getnewaddress()
|
||||
|
|
@ -111,8 +115,10 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vout), 3)
|
||||
assert_equal(tx['fee']['bitcoin'], Decimal('-0.00000326'))
|
||||
assert_equal(decoded['vsize'], 326)
|
||||
assert_equal(decoded['weight'], 1302)
|
||||
self.generate(node0, 1)
|
||||
tx = node1.getrawtransaction(txid, True)
|
||||
assert_equal(tx['discountweight'], 1302)
|
||||
assert_equal(tx['discountvsize'], 326)
|
||||
|
||||
self.log.info("Send confidential (undiscounted) tx to node 1")
|
||||
|
|
@ -127,9 +133,11 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vout), 3)
|
||||
assert_equal(tx['fee']['bitcoin'], Decimal('-0.00002575'))
|
||||
assert_equal(decoded['vsize'], 2575)
|
||||
assert_equal(decoded['weight'], 10300)
|
||||
self.generate(node0, 1)
|
||||
tx = node1.getrawtransaction(txid, True)
|
||||
assert_equal(tx['discountvsize'], 410) # node1 has discountvsize
|
||||
assert_equal(tx['discountweight'], 1302)
|
||||
assert_equal(tx['discountvsize'], 326) # node1 has discountvsize
|
||||
|
||||
self.log.info("Send confidential (discounted) tx to node 1")
|
||||
bitcoin = 'b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23'
|
||||
|
|
@ -148,11 +156,13 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vin), 2)
|
||||
assert_equal(len(vout), 3)
|
||||
if 'bitcoin' in decoded['fee']:
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000410'))
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000326'))
|
||||
else:
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000410'))
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000326'))
|
||||
assert_equal(decoded['vsize'], 2575)
|
||||
assert_equal(decoded['discountvsize'], 410)
|
||||
assert_equal(decoded['weight'], 10300)
|
||||
assert_equal(decoded['discountweight'], 1302)
|
||||
assert_equal(decoded['discountvsize'], 326)
|
||||
|
||||
# node0 only has vsize
|
||||
tx = node0.getrawtransaction(txid, True)
|
||||
|
|
@ -176,11 +186,13 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vin), 2)
|
||||
assert_equal(len(vout), 3)
|
||||
if 'bitcoin' in decoded['fee']:
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000041'))
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000033'))
|
||||
else:
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000041'))
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000033'))
|
||||
assert_equal(decoded['vsize'], 2575)
|
||||
assert_equal(decoded['discountvsize'], 410)
|
||||
assert_equal(decoded['weight'], 10300)
|
||||
assert_equal(decoded['discountweight'], 1302)
|
||||
assert_equal(decoded['discountvsize'], 326)
|
||||
# node0 only has vsize
|
||||
tx = node0.getrawtransaction(txid, True)
|
||||
assert_equal(tx['vsize'], 2575)
|
||||
|
|
@ -207,7 +219,7 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(test[0]["allowed"], True)
|
||||
txid = node1.sendrawtransaction(signed['hex'])
|
||||
tx = node1.gettransaction(txid, True, True)
|
||||
assert_equal(tx['decoded']['discountvsize'], 341)
|
||||
assert_equal(tx['decoded']['discountvsize'], 257)
|
||||
|
||||
for i in range(24):
|
||||
self.log.info(f"Add package descendant {i+1}")
|
||||
|
|
@ -231,7 +243,7 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(test[0]["allowed"], True)
|
||||
txid = node1.sendrawtransaction(hex)
|
||||
tx = node1.gettransaction(txid, True, True)
|
||||
assert_equal(tx['decoded']['discountvsize'], 341)
|
||||
assert_equal(tx['decoded']['discountvsize'], 257)
|
||||
assert_equal(len(node1.getrawmempool()), i + 2)
|
||||
|
||||
assert_equal(len(node1.getrawmempool()), 25)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(decoded['vsize'], 2575)
|
||||
self.sync_mempools([node0, node1])
|
||||
tx = node1.getrawtransaction(txid, True)
|
||||
assert_equal(tx['discountvsize'], 410)
|
||||
assert_equal(tx['discountvsize'], 326)
|
||||
|
||||
feerate = 1.0
|
||||
self.log.info(f"Send confidential (discounted) tx to node 1 at {feerate} sat/vb")
|
||||
|
|
@ -131,11 +131,11 @@ class CTTest(BitcoinTestFramework):
|
|||
assert_equal(len(vin), 2)
|
||||
assert_equal(len(vout), 3)
|
||||
if 'bitcoin' in decoded['fee']:
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000410'))
|
||||
assert_equal(decoded['fee']['bitcoin'], Decimal('-0.00000326'))
|
||||
else:
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000410'))
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000326'))
|
||||
assert_equal(decoded['vsize'], 2575)
|
||||
assert_equal(decoded['discountvsize'], 410)
|
||||
assert_equal(decoded['discountvsize'], 326)
|
||||
|
||||
feerate = 2.0
|
||||
self.log.info(f"Send confidential (discounted) tx to node 1 at {feerate} sat/vb")
|
||||
|
|
@ -145,7 +145,7 @@ class CTTest(BitcoinTestFramework):
|
|||
self.sync_mempools([node1, node2])
|
||||
tx = node1.gettransaction(txid, True, True)
|
||||
decoded = tx['decoded']
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000820'))
|
||||
assert_equal(decoded['fee'][bitcoin], Decimal('0.00000652'))
|
||||
|
||||
# check that txs in the block template are in decreasing feerate according to their discount size
|
||||
self.log.info("Check tx ordering in block template")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue