Bitcoin Development Mailinglist
 help / color / mirror / Atom feed
From: Antoine Riard <antoine.riard@gmail.com>
To: Bitcoin Development Mailing List <bitcoindev@googlegroups.com>
Subject: Re: [bitcoindev] Prohibit Merkle Internal Node Preimages That Encode Minimal 64-Byte Transactions
Date: Sun, 28 Jun 2026 20:40:07 -0700 (PDT)	[thread overview]
Message-ID: <6c02cc0f-13c0-4670-8689-9ad39cd8a203n@googlegroups.com> (raw)
In-Reply-To: <8FEEF72A-92A3-48A9-AC49-43107D17B090@sprovoost.nl>


[-- Attachment #1.1: Type: text/plain, Size: 6401 bytes --]

Hi Jeremy,

Okay, so the main intuition is only a reduction of the "seam" to a specific
structure, by checking that all txid merkle has a specific 1-input, 
1-output,
tx. Would be good if you have benchmark for iterating on a 
max-depth-tree-min
-size tx on a i5 or i7 to have an idea of the perf measurement. Somehow, 
without
more information, I can only echo my protocol colleagues that your solution
is naively coming with more CPU cycles consumption.

On another point, from your discussion with the other Antoine, what is 
observed
is very interesting. It's not only a SPV proof for e.g let's say a bridge 
protocol
using connector output, thar your consideration can be intereesting. It's 
also
that the whole merkle tree can be seen a *scriptable surface*. Assuming that
all the other txn ids are fixed points (easy fulfilled assumption if you're 
a
miner and you can choose the template), a remaining txid slot can be used to
convey *information* from a fixed spent UTXO (where the prover would grind 
on
the remaining entropy bits to get a satisfying solution).

Somehow allowing to build interesting cryptographic puzzles, giving 
zero-knowledge
properties to a simple merkle branch. What theoretically you could do with 
it ?
Super compact proof that a UTXO has been spent and a 1-bit of information 
has
been exchanged. Of course, the current BIP54 fix ruling out 64 bytes tx 
would
still allow to build that kind of proofs, you would just have to special 
case
this in the prover structure.

Anyway, about BIP54, I'm +1 to have a long validation block cost and
timewarp fixes, I'm shrug about getting a better fix for coinbase id 
collision,
we have more time to come with one, ruling out 64 byte tx to make secure SPV
verifier, I've been always less interested by it, personally.

Best,
Antoine
OTS: 62a4928f9aaa678a225f6ca55564049d6ba19ae4d006b890cdfc945248aebb9e

Le Monday, June 22, 2026 à 3:27:54 PM UTC+1, Sjors Provoost a écrit :

>
>
> > Op 1 jun 2026, om 19:46 heeft jeremy <jeremy....@gmail.com> het 
> volgende geschreven:
> > 
> > Esteemed Colleagues,
> > As a result of some of my research on 64-byte transactions, I'd like to 
> discuss an alternative soft fork proposal that preserves the ability to 
> encode 64-byte transactions while offering protection to SPV users (who 
> must make a small patch to validate the path property).
> > The rule, stated simply, is:
> > A block is invalid if any Merkle Tree 64-byte preimage has the exact 
> byte structure of a minimal one-input, one-output, witness stripped 
> transaction.
> > [With the miracle of GPT,] I've drafted a relatively complete BIP for 
> discussion.
>
> I like the idea of fixing the problem as close to the (merkle, haha) root 
> of the problem. But is there a more elegant and succinct way to implement 
> IsForbiddenMerkleInternalNodePreimage64?
>
> Otherwise I prefer to wait 80 years for a proper fix, rather than add this 
> complexity to consensus code. Even if we can't have the 64 byte exception 
> (which I still prefer).
>
> After 2106, the fix can be a simple tweak to the leaf hash calculation:
>
> if (!hardfork) return tx.getHash().ToUint256();
>
> // Fix Merkle tree, and drop the separate witness commitment by committing
> // witness data directly in the transaction Merkle tree.
> return (HashWriter{TaggedHash("TaggedWtxid")} << 
> TX_WITH_WITNESS(tx)).GetSHA256();
>
> Here's a rough sketch:
> https://github.com/Sjors/bitcoin/tree/2026/06/merkle
>
>
> The upgrade mechanism isn't important in this context, but I implemented 
> the following rules:
>
> 1. a new header format, growing timestamp from 32 to 64 bits
> - mask one byte to use for nonce space, if we think two billion years is 
> enough
>
> 2. the block version must be negative, if and only if it uses the new 
> header format
> - let's the header/block deserialiser know in the first 4 bytes how long 
> the header is 
> - current nodes will reject such blocks, because BIP34 deployment burned 
> nVersion < 2
> - therefore it's not used for signalling or nonce grinding
> - no historical blocks have a negative version
>
> 3. new headers must have timestamp >= 2^32 
> - makes it a clean break both ways
> - maybe require old headers can't connect to a new header
>
> - Sjors
>
> > static bool IsForbiddenMerkleInternalNodePreimage64(const unsigned char 
> p[64])
> > {
> > // Minimal 64-byte legacy transaction shape:
> > //
> > // 4 bytes nVersion
> > // 1 byte vin count = 0x01
> > // 36 bytes prevout
> > // 1 byte scriptSig length = x
> > // x bytes scriptSig
> > // 4 bytes nSequence
> > // 1 byte vout count = 0x01
> > // 8 bytes nValue
> > // 1 byte scriptPubKey length = y
> > // y bytes scriptPubKey
> > // 4 bytes nLockTime
> > //
> > // Since the fixed overhead is 60 bytes, x + y must equal 4.
> > 
> > if (p[4] != 0x01) {
> > return false;
> > }
> > 
> > const unsigned int x = p[41];
> > 
> > switch (x) {
> > case 0:
> > if (p[46] != 0x01) return false;
> > if (p[55] != 0x04) return false;
> > break;
> > 
> > case 1:
> > if (p[47] != 0x01) return false;
> > if (p[56] != 0x03) return false;
> > break;
> > 
> > case 2:
> > if (p[48] != 0x01) return false;
> > if (p[57] != 0x02) return false;
> > break;
> > 
> > case 3:
> > if (p[49] != 0x01) return false;
> > if (p[58] != 0x01) return false;
> > break;
> > 
> > case 4:
> > if (p[50] != 0x01) return false;
> > if (p[59] != 0x00) return false;
> > break;
> > 
> > default:
> > return false;
> > }
> > 
> > const size_t value_pos = 47 + x;
> > const uint64_t raw_value = ReadLE64(p + value_pos);
> > 
> > if (raw_value > 
> static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
> > return false;
> > }
> > 
> > const int64_t nValue = static_cast<int64_t>(raw_value);
> > 
> > if (!MoneyRange(nValue)) {
> > return false;
> > }
> > 
> > return true;
> > }
> > 
> > 
>
>

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/6c02cc0f-13c0-4670-8689-9ad39cd8a203n%40googlegroups.com.

[-- Attachment #1.2: Type: text/html, Size: 8152 bytes --]

      reply	other threads:[~2026-06-29  5:32 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-01 17:46 [bitcoindev] Prohibit Merkle Internal Node Preimages That Encode Minimal 64-Byte Transactions jeremy
2026-06-01 18:49 ` 'Antoine Poinsot' via Bitcoin Development Mailing List
2026-06-01 20:17   ` jeremy
2026-06-02 12:36     ` Greg Sanders
2026-06-02 18:15       ` jeremy
2026-06-03  1:05         ` Antoine Riard
2026-06-03 15:07           ` jeremy
2026-06-05 21:34     ` 'Antoine Poinsot' via Bitcoin Development Mailing List
2026-06-09 16:28       ` jeremy
2026-06-09 16:37         ` jeremy
2026-06-15 15:29           ` 'Antoine Poinsot' via Bitcoin Development Mailing List
2026-06-16  2:35           ` Murch
2026-06-09 18:30 ` Matt Corallo
2026-06-15 17:20   ` jeremy
2026-06-16 19:59 ` [bitcoindev] " jeremy
2026-06-16 20:42   ` 'Antoine Poinsot' via Bitcoin Development Mailing List
2026-06-22 14:25 ` [bitcoindev] " Sjors Provoost
2026-06-29  3:40   ` Antoine Riard [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6c02cc0f-13c0-4670-8689-9ad39cd8a203n@googlegroups.com \
    --to=antoine.riard@gmail.com \
    --cc=bitcoindev@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox