public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Peter Todd <pete@petertodd.org>
To: Mike Hearn <mike@plan99.net>
Cc: Bitcoin Dev <bitcoin-development@lists.sourceforge.net>
Subject: Re: [Bitcoin-development] Payment Protocol Proposal: Invoices/Payments/Receipts
Date: Wed, 28 Nov 2012 07:57:10 -0500	[thread overview]
Message-ID: <20121128125710.GA9893@savin> (raw)
In-Reply-To: <CANEZrP1wgMgo8N5f97KF6zNaPzoYVDU9Q=YABkz=jvTpM10jKQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5805 bytes --]

On Wed, Nov 28, 2012 at 11:43:19AM +0100, Mike Hearn wrote:
> Peter is correct that there are a few degrees of freedom in protobuf
> serialization, though far fewer than with JSON.

FWIW I re-read the specs again and turns out my memory was wrong. (I
last looked at this about four months ago) Duplicated fields are handled
in a defined manner, with the last field seen in the serialization being
the one whose value is used. Again, repeated fields are treated as
elements of a list, preserving order.

It does raise the interesting question do the implementations that don't
preserve order of unknown fields, preserve the order of multiple unknown
fields, either repeated or not?

> I'd like to think upstream would be open to resolving these
> ambiguities.

I gotta admit, I suspect they won't be that open. Protocol buffers was
designed because Google needed a fast serialization method suitable for
many different internal projects. Needing round-trip idempotence seems
like a rare requirement to me, especially for internal use.

> Re-serialization of an Invoice message in the Payment message is a
> potential source of mistakes. There's no need to ever concatenate
> these messages and alternative implementations that don't order
> serialized fields by tag number are missing an important optimization,
> so they could be fixed. The main issue is treatment of unknown fields.
> If/when the Invoice message is extended with other fields that are
> round-tripped through an old client, the data may get lost. JSON
> doesn't help resolve that either, of course. There are a few
> solutions:

Well, actually you can take advantage of the message concatination
ability of protocol buffers to extend a message by simply appending the
new fields to the existing thus either defining new fields, or
overriding old values as required. If you want to de-duplicate though
you run into the problem all over again.

On the other hand JSON handles this case fine too provided that your
JSON implementation supports dictionary objects with arbitrary fields.
Just use the object as is and the unknown fields will be re-serialized
properly at the other end. Some implementations will have to be careful
to handle collisions with existing keys in the namespace. (consider in
Python what would happen if you mapped your object to a class instance,
and the serialization included the key "__init__")

That said, JSON is quite problematic with numbers. For instance, you
have to be careful to keep integers represented as pure integers below
what Javascript can handle, the maximum integer exactly representable in
a double float, or the JSON won't be parsable in Javascript even if many
other languages handle it fine. Protocol buffers is at least pretty
explicit about what size integers are.

> 1) Change the type of the Invoice field in Payment to be "bytes" and
> set it to be the hash of the originally received binary Invoice
> message. Downside, requires merchants to track all outstanding
> invoices.
> 2) Ask protobufs upstream to modify the spec/implementations so
> ordering of unknown fields is specified. The Python implementation
> could be extended to support them so Python implementors don't end up
> with accidental message downgrades.
> 3) Language of the spec could be changed to explicitly state that the
> received Invoice may not be binary-identical to the one that was sent,
> in the case of a client that incorrectly downgrades the message. Thus
> you'd be expected to check what the Invoice was using merchant_data
> which is opaque and could just be, eg, a database key on your own end.
> 4) Instead of submitting the entire Invoice back to the merchant, just
> the merchant_data could be in the Payment message.
> 
> Of the four options I prefer the last. What is the use case for
> resubmitting the entire invoice anyway? Even if protobufs are improved

Note that I think the SignedInvoice message itself is broken, because
protobuf implementations have no reason to guarantee that they can give
you the serialized bytes of the Invoice sub-message. It's a quite
specific use-case that isn't needed for pretty much anything but crypto.
FWIW I took a quick look at the official API's, C++, Java and Python,
and as far as I can tell none of them support accessing the binary
serialization of a message field other than by re-serializing the
message.

Really the invoice field should be declared as bytes serialized_invoice,
as inconvenient as that is to work with.

> so handling of round-tripping new messages through old [Python]
> clients is more rigorous, some implementors will probably convert the
> protobuf objects into some internal forms for whatever reason (or
> serialize them to a database, etc) and they're very likely to mess up
> the handling of unknown fields when they do it.

Since the Payment message includes an *untrusted* Invoice that the
vendor needs to authenticate the whole invoice no matter what on Payment
reception. In many cases that implies they have to keep some sort of
database of "quotes" or similar anyway as the client can change anything
they want otherwise. Again that leads back to the argument of why not
just stick with the merchant_dat as you suggest, which will usually be
some short invoice number attached to a database? A vendor that wants to
operation a stateless invoicing system can just stuff a HMAC-protected
serialized invoice into the merchant_data

I guess you could use a mutable invoice field as a way of achieving some
sort of negotiation protocol, but I think it's better to stick to the
original concept of just ensuring that the user is really paying the
right amount to the right address.

-- 
'peter'[:-1]@petertodd.org

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

  reply	other threads:[~2012-11-28 13:59 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-26 22:37 [Bitcoin-development] Payment Protocol Proposal: Invoices/Payments/Receipts Gavin Andresen
2012-11-26 23:02 ` Mike Hearn
2012-11-26 23:13   ` Luke-Jr
2012-11-26 23:16     ` Mike Hearn
2012-11-26 23:19       ` Luke-Jr
2012-11-26 23:27         ` Mike Hearn
2012-11-26 23:32         ` Gregory Maxwell
2012-11-26 23:44           ` Luke-Jr
2012-11-27  0:16             ` Gregory Maxwell
2012-11-27  0:26               ` Mike Hearn
2012-11-27  0:45                 ` Rick Wesson
2012-11-27  1:09                   ` Gavin
2012-11-27  8:44                   ` Mike Hearn
2012-11-27  0:44               ` Luke-Jr
2012-11-26 23:38 ` Rick Wesson
2012-11-26 23:52 ` Jeff Garzik
2012-11-27  0:02   ` Rick Wesson
2012-11-27  0:31     ` Luke-Jr
2012-11-27  0:37       ` Rick Wesson
2012-11-27  2:16 ` Walter Stanish
2012-11-27  2:47   ` Gregory Maxwell
2012-11-27  3:16     ` Walter Stanish
2012-11-27  3:29       ` Rick Wesson
2012-11-27  3:31         ` Walter Stanish
2012-11-27  3:54           ` Rick Wesson
2012-11-27  4:17             ` Walter Stanish
2012-11-27  8:43               ` Michael Gronager
2012-11-27 10:23                 ` Mike Hearn
2012-11-27 10:42                   ` Michael Gronager
2012-11-27 11:36                     ` Pieter Wuille
2012-11-27 11:46                       ` Michael Gronager
2012-11-27 12:03                     ` Mike Hearn
2012-11-27 12:39                       ` Michael Gronager
2012-11-27 14:05                         ` Gavin Andresen
2012-11-27 14:26                           ` Gavin Andresen
2012-11-28 13:55                           ` Walter Stanish
2012-11-27 17:03 ` Andy Parkins
2012-11-27 17:14   ` Mike Hearn
2012-11-27 17:26     ` Andy Parkins
2012-11-27 18:16       ` Mike Hearn
2012-11-27 21:39         ` Gavin Andresen
2012-11-28 10:43           ` Mike Hearn
2012-11-28 12:57             ` Peter Todd [this message]
2012-11-28 14:09               ` Gavin Andresen
2012-11-28  8:33 ` Peter Todd
2012-11-28 23:36 ` Roy Badami
2012-11-29  0:30   ` Watson Ladd
2012-11-29  8:16     ` slush
2012-11-29 16:11   ` Gavin Andresen
2012-11-29 17:07     ` Roy Badami
2012-11-29 17:30       ` Gavin Andresen
2012-11-29 17:31       ` Mike Hearn
2012-11-29 18:53         ` Roy Badami
2012-12-01 19:25           ` Gavin Andresen
2012-12-03 19:35             ` Mike Koss
2012-12-03 20:59               ` Gavin Andresen
2012-12-03 21:28               ` Mike Hearn
2012-12-03 22:26                 ` Roy Badami
2012-12-03 22:34                   ` Jeff Garzik
2012-12-03 22:48                     ` Roy Badami
2012-12-16 21:15               ` Melvin Carvalho
2012-12-17  2:18                 ` Jeff Garzik
2012-12-17  8:24                   ` Melvin Carvalho
2012-12-17  9:19                     ` Mike Hearn
2012-12-17  9:31                       ` Gary Rowe
2012-12-17 11:23                       ` Melvin Carvalho
2012-12-17 17:57                         ` Gavin Andresen
2012-12-20 16:53                           ` Stephen Pair
2012-12-20 17:43                             ` Mike Hearn
2012-12-20 19:32                               ` Stephen Pair
2012-12-21 17:05                                 ` Stephen Pair
2012-12-24  0:38                                   ` Elden Tyrell
2012-12-04 17:06             ` Mike Hearn
2012-12-05 19:34               ` Gavin Andresen
2012-12-06  6:31                 ` Andreas Petersson
2012-12-06  8:53                   ` Mike Hearn
2012-12-06 16:56                     ` Gavin Andresen
2012-12-06 17:55                       ` Mike Hearn
2012-12-06 19:13                         ` Gavin Andresen
2012-12-07 10:45                           ` Mike Hearn
2012-12-07 11:01                             ` Mike Hearn
2012-12-07 16:19                               ` Gavin Andresen
2012-12-07 16:27                                 ` Mike Hearn
2012-12-06 18:13                       ` Alan Reiner
     [not found]                       ` <CALf2ePx5jS@mail.gmail.com>
2014-09-17 19:28                         ` Vezalke
2012-12-03 21:42         ` Gregory Maxwell
2012-12-23  2:33 ` Mark Friedenbach

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=20121128125710.GA9893@savin \
    --to=pete@petertodd.org \
    --cc=bitcoin-development@lists.sourceforge.net \
    --cc=mike@plan99.net \
    /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