Search code examples
xrprippled

Why is a ledger hashed with the close time of its parent ledger?


This seems to be unnecessary because a ledger is hashed with its own close time and its parent's digest (which thus incorporates the parent's close time).


Solution

  • There are transactions that need to know the current time in order to execute correctly. For example, a transaction that trades one asset for another needs to ensure it doesn't execute offers that expired.

    There are really only two places you could get that time. You could get it from the previous ledger's close time or you could get it from this ledger's close time. The option I chose is to use the previous ledger's close time.

    The reason for that choice is that you have to know everything that could affect a transaction result before you can start executing that transaction. Having to know a ledger's close time before you could execute any of the transactions in it would result in significant additional computational expense.

    The software runs every transaction when it is received to make sure the transaction will be able to execute and claim a fee. This is necessary to prevent relaying a transaction that won't claim a fee and allowing free relaying which could lead to denial of service attacks. The more similarly the transaction runs when it executes for real, the less disk I/O and additional computation is needed. So you want to feed the same inputs to the transaction when you run it for real as when you test it. That means using the parent ledger's close time rather than the actual ledger's close time, which is not known until much later.

    So given that we need the parent's close time, why do we put it in the ledger header? There really isn't a particularly good reason. In practice, you need to have the preceding ledger's header in memory to produce the next ledger anyway. However, not putting the previous ledger's close time in the header would mean that if you only had a single ledger, you wouldn't know what the effective time of the transactions was unless you looked at the previous ledger. That would make it harder to understand what rules were applied during order executions or other operations that require a time.

    In summary, the decision to use the previous ledger's close time was done for sound engineering reasons primarily focused around performance in the critical path where transactions are executed "for real". But the decision to put the close time in the ledger header is really just a mild human convenience to make it easier to know what effective wall time was applied for the transactions in the ledger without having to look outside the ledger to know.