CHIP 2021-01 Allow Transactions to be smaller in size

would you want to work on a new message-type in the current p2p layer, or start working on a new message-layer altogether in order to get this rolling?

Ok, suppose you manage it and now there’s a TX and a block with the same hash, what’s the consequence?

I don’t have that much computing power. But I know that it is technically possible, in the same way as it is technically possible to create 64 byte transaction, that would be interpreted as a merkle branch, with two connected 32 byte hashes. Here is how:

+-----------------------+-------------------------+
| blockHeader(80)       | bitcoinTransaction(80)  |
+-----------------------+-------------------------+
| version(4)            | version(4)              |
| previousBlockHash(1)  | inputCount(1)           |
| previousBlockHash(31) | previousTransaction(31) |
| merkleRoot(1)         | previousTransaction(1)  |
| merkleRoot(4)         | previousOutput(4)       |
| merkleRoot(1)         | emptyInputScript(1)     |
| merkleRoot(4)         | sequenceNumber(4)       |
| merkleRoot(1)         | outputCount(1)          |
| merkleRoot(8)         | amount(8)               |
| merkleRoot(1)         | outputScriptSize(1)     |
| merkleRoot(12)        | outputScript(12)        |
| timestamp(4)          | outputScript(4)         |
| targetBits(4)         | outputScript(4)         |
| nonce(4)              | locktime(4)             |
+-----------------------+-------------------------+

By using locktime as a nonce, miners can mine a transaction that would start with many zero bits, and can try to trick users, that they mined some valid block. But only full nodes would know that it is not the case, and that this block is fake. However, to make any serious attack on full nodes, it is needed to form a valid block header and a valid transaction at the same time, then some software bugs of the full nodes could cause some chaos. But it is very, very hard. Probably comparable to 64-byte transaction attack. To make it serious, it is needed to hardcode a lot of bytes to make it valid from both points of view: as a transaction and as a block header. That’s why it is quite unexpected to see some serious attack in the near future, but in theory, it is possible.

When it comes to the consequences, I am still not sure, because I need to read more code. Or maybe we could prepare some test version, where for example SHA-256 is reduced to 16 rounds, then it may be possible to mount some kind of such attacks, and see, how that node would behave.

1 Like

Awesome, thanks for laying it out clearly like that!

We can observe something here: there are at least 32 bytes you can’t possibly match other than by brute-forcing the previous transaction hash (because you must roll the previous transaction contents until you hit your desired hash in this one) which turns this problem into a preimage attack against 256 bits.

If you wanted to make it “easier”, you’d roll both the previous block and the previous transaction simultaneously, which would turn it into a collision search with 128 bits of security but made harder by the fact you need to also match the 0s with the collision. And after finding that so those bits “click”, you’d still need to mine this block, all inside a 10-minute window.

Btw, nonce is not anymore enough to hit a block, and I think difficulty grew enough that miners started rolling parts of version, timestamp and merkle root too! BTC is doing about 200EH/s which translates into some 2^77 attempts per 10-minute block, so you need at least 10 bytes of wiggle room. With BCH it’s lower but still some 1.3EH/s meaning 2^69 and requiring about 9 bytes.

Got a supportive statement from a miner, and permission to quote him:

I do support the TX size one, removing the only case that create confusion instead of a whole range is the way to go.

– checksum0, Bitcoin miner since 2010

1 Like

Regarding the whole != 64 vs >64 debate – I think there is a reason to prefer >64 bytes as the rule.

I’m thinking of lib authors here when I say that for software that authors txns, >64 is a better rule for human reasons and software engineering reasons.

Let me explain why. It’s generally easier on software to have a minimum length of things, this way you are more likely to “trigger” the rule and get an error early if you inadvertently violate the rule. A magical forbidden value of precisely 64 may be “surprising” to some software. 61 works, 62 works, 63 works, etc… but 64, when hit occasionally, fails.

This can be exasperating for someone that is not familiar with all the BCH rules but is building libs to build txns for BCH – if you only hit the magical 64 value 25% of the time, it is strange to you why your txn is rejected and is very surprising behavior. So, the != 64 rule is less likely to fail early. >64 is more likely to be triggered and more likely to “alert” software authors that there is a length rule, so you better watch out!

So for this reason I prefer >64, as @BigBlockIfTrue suggested initially.

3 Likes

It’s also worth noting that Bitcoin Core did this as a >= 82 byte rule (but relay rule only, not consensus since they would have needed to roll this out as a soft fork and they never bothered). So the “>” thing already exists in at least one bitcoin… Just something to keep in mind.

3 Likes

Welp. I decided to just unilaterally implement this in BCHN as >64 (>=65). Motivation: fits in more nicely to existing codebase and logic.

If everybody or anybody hates me for doing it that way and people really really want != 64 instead, just yell at me and call me names and I can change it. I just feel >64 is saner… for the reasons listed in my previous 2 messages as well as for the fact that it just fits into the existing rules in a more homogenous way…

I’ll post a link to my MR in BCHN for this shortly for reference.

I doubt you’ll get much resistance, most people have been ok with either of the two options. If an implementation makes the decision based on practical details, I think that is good enough for most.

But please coordinat via the CHIP as well. So we use the CHIP process instead of “Calin said so” process :wink:

2 Likes

Ok, I’ll update the CHIP. For now my implementation is here: BCH May 2023 Upgrade: Allow for txn sizes as small as 65 bytes (!1598) · Merge requests · Bitcoin Cash Node / Bitcoin Cash Node · GitLab and is ready for merge for Nov and/or for May 2023.

2 Likes

Ok, created an MR for this CHIP here: Update CHIP to talk about a minimum size. (!5) ¡ Merge requests ¡ bitcoincash / CHIPs ¡ GitLab

1 Like