Skip to content

Proposal: Preauthorized transactions with flexible sequence numbers #88

Closed
@robdenison

Description

@robdenison

This proposal would change how preauthorized transactions are checked to allow preauthorization of transactions without committing to a specific sequence number.

Under the current behavior, a signer of type preAuthTx is checked by comparing the hash of the unaltered transaction to the hash specified in that signer. This proposal would change that behavior so that the signer can also be satisfied if the hash of the transaction with its sequence number changed to 0 (or some other magic number) matches the hash specified in the signer.

All other transaction behavior would remain the same. The transaction ID would still include the sequence number (so all transactions would still have unique sequence numbers). The sequence number of the transaction would still be incremented by one if the transaction succeeds. The preauthorized transaction would be removed from the account when it is used, preventing it from being replayed.

EDIT: We could apply this behavior to signed transactions as well as preauthorized transactions, which would be particularly useful for Starlight. These transactions should only be used in protocols that ensure through other means (such as by having the transaction change the signers on the account) that they cannot be replayed.

Rationale

It is sometimes useful to preauthorize a transaction without knowing what its sequence number will be. It is particularly useful to be able to preauthorize multiple transactions without knowing ahead of time the order in which they will be published to the chain.

For example, this change would significantly reduce the overhead and complexity of hashed timelocked contracts (HTLCs) on payment channels in Stellar Lightning. HTLCs are agreements that can be concluded in two ways—by revealing a hash preimage, which results in some steps (such as a payment) being "fulfilled," or by satisfying a timeout, which results in those steps being "cancelled." They can be implemented in Stellar (with some other unrelated protocol changes). However, it is currently difficult to set up a payment chanel with multiple HTLCs (as is required by Lightning), because those HTLCs need to be fulfillable or cancelable in any order. The most efficient known way to implement them in the current protocol would involve preauthorizing a separate aggregate key for each HTLC and pre-signing N fulfill and N cancel transactions for each HTLC, with O(N^2) off-chain overhead. This method also appears to have other limitations (for example, each HTLC fulfillment would likely be limited to a single operation).

Alternatives

An alternative would be to not increment the sequence number when such a condition is satisfied. This would be a more radical change to the protocol and implementation (even though it would still not allow replay) and would violate some invariants.

A more radical design would be to allow transactions with sequence numbers of 0 to be valid regardless of the current sequence number of the account. This would be strictly more powerful than this proposal, but is potentially much more dangerous (since a signed transaction with a 0 sequence number would be replayable any number of times, unless it changed the state in some other way that prevented it from being replayed). However, such a design could be very useful. One potential application is to be able to pre-sign transactions from an account that has not yet been created (and whose starting sequence number is therefore unknown). This would allow you to pre-sign a series of transactions that create a new account and endow it with arbitrary signers, which is currently impossible (and which could be used as an alternative way to implement HTLCs or a host of other smart contract designs).

A final option would be to add flexible preauthorized transactions as a new signer type, or as a flag that can be set on the preAuthTx signer type. This would be a more extensive change to the implementation and the product's surface area, but might avoid even a small risk of upending user expectations (see Backwards Compatibility.

Implementation

The signature checker could be initialized with an additional argument—the hash of the transaction with its sequence number changed to 0. The preAuthTx signer check would check for equality with either the hash of the transaction or this alternative hash.

The additional overhead would be the computation of this hash for each transaction that is checked, and an extra 32-byte comparison for each preAuthTx signer that is checked. (This could be optimized by only computing this hash lazily, when a preauthorized transaction signer check fails.)

Backwards Compatibility

This will make previously invalid (unauthorized) transactions valid, making it a breaking consensus change.

This probably will not cause any breaking changes in application or user code. This change does not make any previously valid transactions invalid. Additionally, as far as I know, there is currently no reason to preauthorize transactions with a sequence number of 0 (and no way to satisfy such preauthorized transactions), so nobody should have been relying on this behavior.

However, it is possible that some application code might rely on some situational invariant that is broken by this change. For example, this breaks the invariant that an account whose only signer is a preauthorized transaction can only be updated by a transaction whose hash matches that one precisely. If any application code relies on watching for a particular user-specified preauthorized transaction hash, this change might disrupt it. As far as I can tell, there is no reason for an application to watch for updates to an account in this way (rather than watching the account directly).

Forwards Compatibility

It is possible that future proposals may want to use a 0 sequence number for some other, incompatible feature.

One possible feature would be to allow transactions themselves to have a 0 sequence number (as described above in Alternatives). This would be its own breaking consensus change, but would be completely compatible (from the user and application perspective) with this proposal. A user on an account with a preauthorized 0-sequence-number transaction would simply have the additional option of publishing the 0-sequence-number transaction itself.

If an incompatible use of a 0 sequence number were developed (such as one where the transaction did not increment the account's sequence number), it could always use some other magic number, such as -1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CAPRepresents an issue that requires a CAP.stale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions