Skip to content

Latest commit

 

History

History
163 lines (124 loc) · 6.11 KB

cap-0011.md

File metadata and controls

163 lines (124 loc) · 6.11 KB

Preamble

CAP: 0011
Title: Relative Account Freeze
Author: Jeremy Rubin
Status: Draft
Created: 2018-11-14
Discussion: https://github.com/stellar/stellar-protocol/issues/90
Protocol version: TBD

Simple Summary

This CAP introduces a locking signer which allows for relative time locks of accounts.

Abstract

In stellar, transactions are allowed to condition their validity based on time. However, because time is defined to be absolute, and the time at which events are confirmed into the ledger are non-deterministic, this makes it difficult to reason about the scheduling of events in complex contracts. Furthermore, transaction validity ranges don't exclude the possibility of another transaction with a different time range being availabke,

To address this partially, we introduce the notion of a time lock at the account level which may be absolute or relative. This construct provides flexibility for contract designers to sequence time based events easily and circumvent the need for periodic updates in time based protocols.

Motivation

Currently, transactions may specify a valid after and valid before date range. However, this range is absolute so it does not permit protocols that specify for some action to happen after another action without knowledge of the exact timing. This makes writing channel protocols difficult as they typically require periodic updates. See here.

A relative timeout signer

Specification

enum SignerKeyType
{
    SIGNER_KEY_TYPE_ED25519 = KEY_TYPE_ED25519,
    SIGNER_KEY_TYPE_PRE_AUTH_TX = KEY_TYPE_PRE_AUTH_TX,
    SIGNER_KEY_TYPE_HASH_X = KEY_TYPE_HASH_X,
	SIGNER_KEY_TYPE_TIMEOUT = 11
};

enum TIMEOUT_FLAGS {
    TIMEOUT_FLAGS_SEQUENCE_RELATIVE = 1,
    TIMEOUT_FLAGS_CLOCK_RELATIVE = 1<<1,
    TIMEOUT_FLAGS_REMOVABLE = 1<<2,
    TIMEOUT_FLAGS_NO_AUTOREMOVE = 1<<3,
    TIMEOUT_FLAGS_ONLY_BUMPSEQ = 1<<4,
    TIMEOUT_FLAGS_NO_BUMPSEQ = 1<<5,
    TIMEOUT_FLAGS_ALLOW_HI = 1<<6,
    TIMEOUT_FLAGS_ALLOW_MID = 1<<7,
    TIMEOUT_FLAGS_ALLOW_LOW = 1<<8,
};

union SignerKey switch (SignerKeyType type)
{
case SIGNER_KEY_TYPE_ED25519:
    uint256 ed25519;
case SIGNER_KEY_TYPE_PRE_AUTH_TX:
    /* SHA-256 Hash of TransactionSignaturePayload structure */
    uint256 preAuthTx;
case SIGNER_KEY_TYPE_HASH_X:
    /* Hash of random 256 bit preimage X */
    uint256 hashX;
case SIGNER_KEY_TYPE_TIMEOUT:
	struct {
		uint64 flags;
		int64 original_closeTime;
		int64 actual_closeTime;
		uint32 original_ledgerSeq;
		uint32 actual_ledgerSeq;
	} locktill;
};

When a timeout key is added to an account, the accounts seuence number may not be increased until the current ledger sequence and most recent close time are both greater than or equal to the times specified in the SIGNER_KEY_TYPE_TIMEOUT. The actual_ fields may be set to an arbitrary value and are filled in upon receipt of the relative locktime with the actual computed time. The original_ fields are set to the actual_ fields value before they are modified. Transactions where the account is not the source may still succeed while the timeout is present unless otherwise specified.

If the relative seq and time flags are set then when the entry is added the timeout is computed relative to the execution time of the transaction adding it. For example, were it to be 100 ledgers relatively and it was added at ledger 64534, then the next sequence adjusting transaction could happen at ledger 64634.

If the REMOVABLE flag is set, then the timeout may be removed by a transaction which has a different source account. If it is not set, the timeout may not be removed until it has matured.

If NO_AUTOREMOVE is set, then the key does not delete itself automatically off of the account once satisfied. If it is unset, the signer removes itself automatically once satisfied. To manually remove a relative signer, it should be referred to with the original_ fields set to the acutal_ value it was set to be when added.

If ONLY_BUMPSEQ is set, then the only operation that may use the account as a source is a BUMPSEQ.

If NO_BUMPSEQ is set, then BUMPSEQ may not use the account as a source of an operation.

If ALLOW_MID or ALLOW_HI are set, then the timeout may be overrided by a MID or HIGH threshold set of signers. ALLOW_LOW option is provided even though in most cases it is useless. However, if the account is set to have signers below the threshold, and a contract path has the effect of decreasing the threshold, perhaps it is desired to then ignore the timeout.

Rationale

This design covers the various use cases discussed for timeouts.

For example, in a ratchet account for starlight channels, you Bump Sequence and then add a relative timeout of the desired period. This gives the counterparty sufficient time to come online to counterclaim. The relative timeout removes the need to periodically sign update transactions. This improves the security and simplicity of channel implementations.

Strictly speaking, for this use case we minimally need the relative timeout version of only one time field (ledger sequence or time), and do not need the other flags except for NO_AUTOREMOVE. NO_AUTOREMOVE is useful for keeping signer reserves reserved until the end of the protocol.

If allowed to be set though, the other options allow for a more flexible model for contracting with timeouts between when certain operations may take place. BUMPSEQ is exempted by default if the account should be restricted for outside operations, given that it's standard use is for timeout based protocols.

The complexity around the swapping of the original_ and actual_ values allows for a contract designer to have a time invariant identifier for identical relative timeouts added at different times. Without this, removing timeouts could only be done by transactions which are signed after observing the relative times computed.

Backwards Compatibility

The signer is 32 bytes so should be compatible.

Old software must be able to understand when an account is locked.

Technically, this change is equivalent to removing keys from an account from the perspective of another account.

Implementation

None yet.