<p>In the rust-bitcoin code, the 160 is a minimum weight, denominated in weight units, not size. 160 weight units corresponds to 40 (virtual) bytes.</p>
<p>In the Bitcoin Core coin selection unit test, the 150 is a virtual size, denominated in virtual bytes. In weight units, it would be 600.</p>
<p>The smallest an input could be is 41 vbytes. This happens to be 41 actual bytes as well, and is 164 weight units. This input would be composed of the 32 byte txid, 4 byte output index, 1 byte scriptSig, and 4 byte sequence. As there is no witness data, each physical byte translates to 4 weight units.</p>
<p>The rust-bitcoin code is specifically excluding all script and witness data, so the 1 byte scriptSig is excluded from their calculation, hence 160 weight units.</p>

CC BY-SA 4.0
2024-11-09T20:45:10.040Z
I see thanks.  It wasn't clear to me if the 150 in the tests was bytes or Vb.  If it's Vb then that resolves the other problems I had with calculations.  And yes, I am aware that in rust-bitcoin, the computation starts at 40 vB. I guess I should have started there instead of using 160 bytes.
yancy
CC BY-SA 4.0
2024-11-09T22:44:45.063Z
Bytes are irrelevant for feerate. Only weight or vbytes matter.
Pieter Wuille
CC BY-SA 4.0
2024-11-09T23:00:05.207Z
I think you meant fee not feerate?
yancy
CC BY-SA 4.0
2024-11-09T23:53:38.723Z
In rust-bitcoin, the FeeRate module implicitly converts to the units sat/kwu where in bitcoin-core, it looks like the units are sat/vB.  I was able to make a unit test with the same results as bitcoin core using `FeeRate::from_sat_per_vb(5)` and `Weight::from_vb_unwrap(110)` which gives the same results as in core `fee_rate = 5000` and `weight = 150`
yancy
CC BY-SA 4.0
2024-11-10T14:55:54.973Z
@yancy I meant that feerates are always expressed per vbyte, weight units, or multiples thereof. Bytes (as in total serialized size) is just conceptually irrelevant for fee-related reasoning.
Pieter Wuille
CC BY-SA 4.0
2024-11-18T15:25:40.213Z
@PieterWuille in rust-bitcoin, functions either return usize (u32 or u64) or Weight, so this is what I mean when I say bytes or Weight.  For example base_size of an input: https://github.com/rust-bitcoin/rust-bitcoin/blob/dbedac1bffa9f35c9c6b1a818d6a195ebb06cf46/bitcoin/src/blockdata/transaction.rs#L137.  Conceptually bytes or usize here is vbytes not weight.
yancy
CC BY-SA 4.0
2024-11-18T15:31:56.943Z
Yes, but I still don't understand what you mean with "fee not feerate". I'm not talking about code at all. Just the concept of feerate isn't applicable to bytes.
Pieter Wuille
CC BY-SA 4.0
2024-11-19T00:40:58.563Z
fee_rate is a ratio of either sats divided by Weight Units or sats divided by vbytes (which I am confusing the issue by calling bytes).  I don't think we disagree.
yancy
CC BY-SA 4.0
2024-11-19T01:40:15.703Z
and yes, fee is not applicable to bytes, sorry for the confusion
yancy
CC BY-SA 4.0
2024-11-09T20:30:51.130Z
2024-11-09T20:30:51.130Z
Ava Chow
<p>In the bitcoin-core reference client, <code>CFeeRate::GetFee</code> is a function of <code>num_bytes</code>.  What is the smallest amount of <code>num_bytes</code> that a <code>TxIn</code> can be in practice as it pertains to calculating that inputs effective value?  The reason I ask is that there are some test cases in the core wallet that use <a href="https://github.com/bitcoin/bitcoin/blob/0903ce8dbc25d3823b03d52f6e6bff74d19e801e/src/wallet/test/coinselector_tests.cpp#L1227" rel="nofollow noreferrer">150 bytes</a> which seems unrealistic.  The transaction calculator shows taproot as the most compact at 57.5 vB or 230 bytes I believe.  The reason why 150 bytes is problematic is that it's difficult to faithfully  reproduce that calculation using the rust-bitcoin framework for example, since the effective_value calculation implies at least inputs of <a href="https://github.com/rust-bitcoin/rust-bitcoin/blob/7df5e7c1bcb4aaf3247f0b76591db9744f03425e/bitcoin/src/blockdata/transaction.rs#L801" rel="nofollow noreferrer">160 bytes</a> due to the output and sequence size implicit in all effective_value calculations.  Of course, a test could be made for 160 bytes instead which would probably have identical results, although I'm mostly curious why 150 bytes was selected here and if there's some practical oversight in the rust-bitcoin effective-value calculation.</p>

<transaction-weight><coin-selection><utxo-management>
How light can an input be?
yancy
# How light can an input be?

(Asked by: username_0 on 2024-11-09)

In the bitcoin-core reference client, `CFeeRate::GetFee` is a function of `num_bytes`. What is the smallest amount of `num_bytes` that a `TxIn` can be in practice as it pertains to calculating that inputs effective value? The reason I ask is that there are some test cases in the core wallet that use [150 bytes](https://github.com/bitcoin/bitcoin/blob/0903ce8dbc25d3823b03d52f6e6bff74d19e801e/src/wallet/test/coinselector_tests.cpp#L1227) which seems unrealistic. The transaction calculator shows taproot as the most compact at 57.5 vB or 230 bytes I believe. The reason why 150 bytes is problematic is that it's difficult to faithfully reproduce that calculation using the rust-bitcoin framework for example, since the effective\_value calculation implies at least inputs of [160 bytes](https://github.com/rust-bitcoin/rust-bitcoin/blob/7df5e7c1bcb4aaf3247f0b76591db9744f03425e/bitcoin/src/blockdata/transaction.rs#L801) due to the output and sequence size implicit in all effective\_value calculations. Of course, a test could be made for 160 bytes instead which would probably have identical results, although I'm mostly curious why 150 bytes was selected here and if there's some practical oversight in the rust-bitcoin effective-value calculation.

**Tags:** transaction-weight, coin-selection, utxo-management


---

## 1 answers

### Answer by username_1 on 2024-11-09. Score: 4 | Accepted answer

In the rust-bitcoin code, the 160 is a minimum weight, denominated in weight units, not size. 160 weight units corresponds to 40 (virtual) bytes.

In the Bitcoin Core coin selection unit test, the 150 is a virtual size, denominated in virtual bytes. In weight units, it would be 600.

The smallest an input could be is 41 vbytes. This happens to be 41 actual bytes as well, and is 164 weight units. This input would be composed of the 32 byte txid, 4 byte output index, 1 byte scriptSig, and 4 byte sequence. As there is no witness data, each physical byte translates to 4 weight units.

The rust-bitcoin code is specifically excluding all script and witness data, so the 1 byte scriptSig is excluded from their calculation, hence 160 weight units.

> **Comments:**
> **username_0**: I see thanks.  It wasn't clear to me if the 150 in the tests was bytes or Vb.  If it's Vb then that resolves the other problems I had with calculations.  And yes, I am aware that in rust-bitcoin, the computation starts at 40 vB. I guess I should have started there instead of using 160 bytes.  
> **username_2**: Bytes are irrelevant for feerate. Only weight or vbytes matter.  
> **username_0**: I think you meant fee not feerate?  
> **username_0**: In rust-bitcoin, the FeeRate module implicitly converts to the units sat/kwu where in bitcoin-core, it looks like the units are sat/vB.  I was able to make a unit test with the same results as bitcoin core using `FeeRate::from_sat_per_vb(5)` and `Weight::from_vb_unwrap(110)` which gives the same results as in core `fee_rate = 5000` and `weight = 150`  
> **username_2**: @username_0 I meant that feerates are always expressed per vbyte, weight units, or multiples thereof. Bytes (as in total serialized size) is just conceptually irrelevant for fee-related reasoning.  
> **username_0**: @username_2 in rust-bitcoin, functions either return usize (u32 or u64) or Weight, so this is what I mean when I say bytes or Weight.  For example base_size of an input: https://github.com/rust-bitcoin/rust-bitcoin/blob/dbedac1bffa9f35c9c6b1a818d6a195ebb06cf46/bitcoin/src/blockdata/transaction.rs#L137.  Conceptually bytes or usize here is vbytes not weight.  
> **username_2**: Yes, but I still don't understand what you mean with "fee not feerate". I'm not talking about code at all. Just the concept of feerate isn't applicable to bytes.  
> **username_0**: fee_rate is a ratio of either sats divided by Weight Units or sats divided by vbytes (which I am confusing the issue by calling bytes).  I don't think we disagree.  
> **username_0**: and yes, fee is not applicable to bytes, sorry for the confusion  

---

