Skip to content

Feedback on specification #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
craigraw opened this issue Nov 23, 2023 · 4 comments
Closed

Feedback on specification #2

craigraw opened this issue Nov 23, 2023 · 4 comments

Comments

@craigraw
Copy link

As requested, my feedback. It's difficult to consider this without comparing against the dominant BC-UR standard. The major advantage compared to BC-UR seems to be the simplicity of the scheme. However, there are several drawbacks:

  • The efficiency of an animated QR scheme should not be measured in the minimum number of QRs required in the sequence, but the number of QRs that constitute a successful data transfer in practice. It is common when scanning that some QRs in a sequence are missed, due to movement of the hand holding the display device, differences in display and scan rates etc. This scheme does not use fountain codes, and thus any missed QRs means total number of QRs in the sequence must be scanned again.
  • The maximum number of QRs is limited to 255 in the sequence, which means on version 21 a maximum transfer size of 270810 bytes. I have just created a segwit PSBT with 100 inputs at 272k. Even if compression would make this particular transfer possible, it seems too low a limit to cater for all situations. Consider further the need to include the entire previous transaction in the PSBT non-witness field for legacy script UTXOs, and some hardware wallets that require both the non-witness and witness fields regardless!
  • "Your software would need to be pretty dumb to accept a PSBT file when it was expecting a list of seed words!" Many interfaces, especially mobile ones, use a global/general purpose QR scanning interface element, for example on the top left of the wallet application home screen. If the type of the data that has been scanned cannot easily be determined, the content must be guessed at ala mimemagic. Even with a more specific interface element, the type of the data expected must be specified upfront, rather than reacted to. This is inherently less flexible and puts more burden on the scanning application. IMO well defined types should always be preferred in communication protocols.
  • The current specification restricts itself to types which already have a well-defined data structure, like transactions and PSBTs. Other types like seed words, output descriptors, message signing parameters and xpub exports are less well defined. Without any standards for these, developers are likely to invent their own resulting in reduced compatibility, and more headaches for coordinator wallets that must support an ever-changing variety of possible formats.

BC-UR does not have these drawbacks, so they must be weighed against the simplicity of implementation. I can't speak knowledgeably to the capability of embedded devices, but certainly it has been possible for many hardware wallet implementors to send and receive BC-UR formatted QRs.

Further, this adds another QR standard. While it is simple to add support for scanning this format, with BC-UR already well established the choice of which standard to use when displaying an animated sequence must probably be left to the user, burdening them with a technical detail they are unlikely to understand. There should be a very good reason to have to put in the effort of educating an entire userbase, and adding this additional complexity to the UX flow of many common operations.

@doc-hex
Copy link
Contributor

doc-hex commented Nov 24, 2023

  • This scheme does not use fountain codes, and thus any missed QRs means total number of QRs in the sequence must be scanned again.

Correct. However, the "sender" could repeat the individual QRs (interleaved randomly) to achieve the same sort of forward error correction.

.. number of QRs is limited to 255 in the sequence ..

I've just changed it to use base 36 numbers in the header. It's still 8 characters total, but can now encode up to 1295 QR codes in a series. I'm curious what the practical limit will be for normal use, but 255 QR's felt too low and we were wasting those bits in the header anyway. Coldcard can handle PSBT files up to 2 megabytes, and this can transfer them... but I think higher counts only make sense when the QR itself is quite small.

[mimetypes vs. guessing]

We can support up to 36 or so different encodings, so I felt we should start small. For the JSON, CBOR and Text encodings, the contents are typically self-describing anyway, so no need to repeat that at this layer. If there are other binary file formats specific to Bitcoin use, I'm happy to add them.

The current specification restricts itself to types which already have a well-defined data structure..

Yes, by design.

Further, this adds another QR standard..

We would normally work within existing standards, but some standards are just too complex for their value-add.

@seedhammer
Copy link

  • This scheme does not use fountain codes, and thus any missed QRs means total number of QRs in the sequence must be scanned again.

Correct. However, the "sender" could repeat the individual QRs (interleaved randomly) to achieve the same sort of forward error correction.

Repeating individual QRs doesn't help, because you may end up repeating fragments the client already have and delay the ones they don't. In fact, fountain codes is an extension of your idea that does help: a single QR may contain several fragments XOR'ed together and can achieve the desirable property that any k+e QRs can recover a k partitioned data, where e is small with high probability.

I believe the lack of erasure coding seems like the biggest disadvantage of BBQr. FWIW, I estimate implementing fountain codes from scratch is less work than implementing even the limited zlib codec mandated by the BBQr spec. You need a pseudo random function, code to output a random subset of your fragments to be XOR'ed together. On the receiving side, you track XOR'ed fragments so you can factor out constituent fragments when they arrive.

@craigraw
Copy link
Author

I should note that BBQR has another major advantage over BC-UR - efficiency when using base32 encoding and compression. As an example:

669 byte PSBT, single QR

UR: 1367 chars

BBQr HEX: 1346 chars (669*2+8)
BBQr BASE32: 1079 chars
BBQr ZLIB: 727 chars

The bytewords encoding used by BC-UR is roughly as efficient as hex encoding. Base32 encoding provides significant savings, and performing compression of the data adds on top of that.

@nvk
Copy link
Contributor

nvk commented Mar 7, 2024

Implemented ;)

sparrowwallet/sparrow@9e4eed9

@nvk nvk closed this as completed Mar 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants