diff --git a/tips/TIP-0038/assets/backdating-blocks.png b/tips/TIP-0038/assets/backdating-blocks.png new file mode 100644 index 000000000..9c3b1c32c Binary files /dev/null and b/tips/TIP-0038/assets/backdating-blocks.png differ diff --git a/tips/TIP-0038/chain-constraint.png b/tips/TIP-0038/assets/chain-constraint.png similarity index 100% rename from tips/TIP-0038/chain-constraint.png rename to tips/TIP-0038/assets/chain-constraint.png diff --git a/tips/TIP-0038/assets/expiration-uc-example.png b/tips/TIP-0038/assets/expiration-uc-example.png new file mode 100644 index 000000000..a739d66e5 Binary files /dev/null and b/tips/TIP-0038/assets/expiration-uc-example.png differ diff --git a/tips/TIP-0038/tip-0038.md b/tips/TIP-0038/tip-0038.md index 3e2657bd9..e2c585d99 100644 --- a/tips/TIP-0038/tip-0038.md +++ b/tips/TIP-0038/tip-0038.md @@ -105,7 +105,7 @@ the state forward. The **state can be updated according to the transition rules its current state**. As a consequence, each such output has a unique successor, and together they form a path or _chain_ in the graph induced by the UTXO spends. Each chain is identified by its globally unique identifier. -![](chain-constraint.png) +![](./assets/chain-constraint.png) Account outputs, foundry outputs, and NFT outputs all use this chain constraint concept and define their own unique identifiers. @@ -960,7 +960,7 @@ follows: ## Expiration Unlock Condition Index Bounds -In theory, the choice of bounded slot indices on the _Expiration Unlock Condition_ is ideal when the `Address` and +In theory, the conditions for a successful unlock on the _Expiration Unlock Condition_ are ideal when the `Address` and `Return Address` pick the commitment most suitable to them, i.e. the oldest (`Maximum Committable Age` old) and newest (`Min Committable Age` old) one, respectively. In practice, however, it is likely that a node will provide a commitment within the range of maximum and minimum committable age. If both pick the same commitment this causes a period of time @@ -968,7 +968,12 @@ within the range of maximum and minimum committable age. If both pick the same c However, this deadzone is more desirable than the alternative, where for some overlapping period of time, both `Address` and `Return Address` would be able to unlock the output, potentially allowing a double spend. -**Example with optimal Commitment Input choice** +![](./assets/expiration-uc-example.png) + +_In this figure, Block A and B are issued in the slot corresponding to the current Wall Clock Time respectively (which +is not globally the same in this example). It shows how the choice of the commitment affects the unlocking outcome._ + +**Example with optimal Commitment Input choices** Suppose that `Minimum Committable Age` is 3 and `Maximum Committable Age` is 10, and there is an Expiration Unlock Condition with `Slot Index` set to 20. Note the restrictions on the Commitment Input within a transaction relative to a @@ -983,6 +988,40 @@ If however, the current slot is 18, and both owners would use the same Commitmen of 8 and 15 of possible commitments, then neither one of them can unlock the output, as neither 20 > 13+10 nor 20 <= 13+3 is true. +**Backdating blocks** + +One variable that was not mentioned yet is how a client can set a block's `Issuing Time`, relative to which the chosen +commitment is validated, which allows for _backdating_ blocks. Backdating blocks by a singificant amount is only +possible when there is liveness. The most that someone can backdate a block is to +`Accepted Tangle Time - Liveness Threshold Upper Bound`, so if there is liveness (`ATT ~= Wall Clock Time`), then the +most someone could backdate their block is by `Liveness Threshold Upper Bound`. + +![](./assets/backdating-blocks.png) + +_This figure shows an example of backdating a block by one slot (which is less than `Liveness Threshold Upper Bound`). +The global Wall Clock Time is the same for both blocks and yet both transactions in their respective blocks could unlock +the output._ + +The only time that backdating has any consequence is if there is liveness. Assume some application (for example, a layer +2 chain) relies on an expired output being consumed. The application should only consider the expired output as consumed +and act on that if the output is at least accepted, but ideally until it is committed, confirmed or finalized. The +higher the level of finality the application waits for, the more difficult it is for the `Address` owner (the receiver +of the output with an _Expiration Unlock Condition_) to backdate a block and revert the consumption of the expired +output. For example, if the application waits for commitment of the expired output being consumed, then it is impossible +for the receiver address to subsequently consume it, unless it forces a chain switch, because the receiver address can +only consume the output in an earlier slot than the return address can consume it, and all such earlier slots are +already committed. If the application only waits for acceptance of the expired output consumption, a malicious owner of +the receiver address could technically issue a backdated block shortly after `ATT - Liveness Threshold Upper Bound`, but +this block would be less likely to be selected as a tip, and because the majority of online validators already accepted +the expired output consumption, they should not accept the backdated receiver consumption because it is a conflict. The +only way the receiver address could revert the other conflict is by having support of a majority of other validators to +revert it. In conclusion, it is very difficult to backdate even with just acceptance, and becomes more difficult when +waiting for higher levels of finality. This attack relates to the fundamental fact that the best approximation of time +is the block's `Issuing Time` timestamp, which is is meant to be very difficult to falsify. + +**Note**: An IOTA Smart Contract Chain is not susceptible to such a backdating attack anyway because it is the receiver +address of the expiration locked output and it is _not_ waiting for the output to expire in order to consume it. + # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).