ECIP 1105: Ancestor Hash Appended Type Transactions Source

AuthorIsaac
Discussions-Tohttps://github.com/ethereumclassic/ECIPs/issues/422
StatusDraft
TypeStandards Track
CategoryCore
Created2021-04-20
Requires EIP-2718, EIP-2930

Simple Summary

Defines a new transaction type that has a field for a constraint on ancestor block hash. Transactions with this field are only valid on chain segments that include the defined ancestor.

Abstract

We introduce a new EIP-2718 transaction type with the format 0x4 || rlp([chainId, ancestorHash, nonce, gasPrice, gasLimit, to, value, data, access_list, yParity, senderR, senderS]).

This proposed ancestorHash element adds a constraint on the validity of a transaction to a chain segment containing the cited ancestor in its graph.

Motivation

Establish a protocol-based mechanism with which transactions are able to articulate a constraint on some chain state.

Generally, this constraint gives the consumer (the transactor) an ability to express requirements about the transaction’s relationship to blockchain data and its provenance.

  • Restrict transaction applicability to a chain context that is currently available and reasoned about under some subjective view.
    • Introduces a way for transactions to describe a dependency on their current view of a chain.
  • Restrict transaction applicability to a chain context following some foregoing block (and its transactions).
    • Introduces a way for transactions to describe ancestral dependencies at a “macro” (block) level. Indirectly, this offers a way for a transaction to depend on the presence of another, so long as the dependent transaction is in a different block.

Specification

Parameters

  • FORK_BLOCK_NUMBER TBD
  • TRANSACTION_TYPE_NUMBER 0x4. See EIP-2718.

As of FORK_BLOCK_NUMBER, a new EIP-2718 transaction is introduced with TransactionType TRANSACTION_TYPE_NUMBER.

The EIP-2718 TransactionPayload for this transaction is rlp([chainId, ancestorHash, nonce, gasPrice, gasLimit, to, value, data, access_list, yParity, senderR, senderS]).

The EIP-2718 ReceiptPayload for this transaction is rlp([status, cumulativeGasUsed, logsBloom, logs]).

Definitions

Validation

The values defined below act as a constraint on transaction validity. Transactions defining constraints which are not satisfied by their chain context should be rejected as invalid. Blocks containing invalid transactions should be rejected as invalid themselves, per the status quo.

ancestorHash

  • ancestorHash bytes. A byte array 32 bytes in length.

The ancestorHash is a reference to a specific block by hash. If a transaction filling this field is included in block number n, the annotated value must match some block numbered <= n-1 and existing as a direct (canonical; non-ommer) ancestor of the transaction’s containing block. A “direct ancestor” means that the hash of the block must exist in the parentHash tree of the chain.

The ancestorHash value should be RLP encoded as a byte array for hashing and transmission.

Rationale

The ancestorHash field allows the transactor to express and guarantee an assumption about some contemporary chain state for their pending transaction.

Reference to some assumed blockchain state for transaction composition is already the common case. A transaction sender might reference their view of the chain to fill the transaction’s nonce field, to check their balance, and even to determine the availability or pricing of some op code (via a hypothetical fork upgrade).

Currently, these references to a chain state during transaction composition are tacit and passive. If the transactor’s assumption breaks, their transaction may yield an unintended or undesired outcome. ancestorHash facilitates the declaration of these state assumptions, and demands their correctness in order for the transaction to be permitted.

Chain state on Ethereum only approaches finality, while its transactions are subject to somewhat arbitrary inclusion and ordering. This mechanism allows transactors to express demands about foregoing chain state for the eligibility of their transactions.

In this way, ancestorHash values can operate as an observable heuristic for confidence (on behalf of transactors) about the finality of the chain state. These measurements could be used to inform confirmation delay values of creditors.

Example Scenarios

Finality duping

Elon owns 1000000ETH. Fred owns 100ETH. Elon issues a transaction sending his balance to a known currency exchange, apparently selling this share in the currency. This transaction is included at block number 1,000,000 with hash 0xb2957ab683ae69176b2eb7858f2baedb93752cb7cb45284529d543eebe20652e.

Upon the publication of this block, Fred sees this transaction and thinks that he should follow in Elon’s footsteps to protect his capital from speculative devaluation. Fred constructs and publishes a similar transaction, which he expects to be included in some subsequent block.

By accident or design, block 0xb2957ab683ae69176b2eb7858f2baedb93752cb7cb45284529d543eebe20652e is orphaned, replaced with 0x51c7fe41be669f69c45c33a56982cbde405313342d9e2b00d7c91a7b284dd4f8. This replacement block does NOT contain Elon’s transaction (or contains an alternative, replacement transaction from Elon), but it does contain Fred’s transaction.

Fred has been duped into a sale, while Elon hodls and profits.

If Fred can cite 0xb2957ab683ae69176b2eb7858f2baedb93752cb7cb45284529d543eebe20652e as an ancestorHash dependency, his transaction will be inapplicable on the newly reorganized chain, and he won’t get duped.

Double-spend

Transactions citing ancestors on a public chain will not be valid on an attacker’s secret chain if the citations reference post-fork blocks.

Under the current protocol conditions, a double-spend attacker can choose to include none, some, or all-but-one of the public chain’s transaction on their attack chain.

We assume for the sake of this scenario’s argument that all transactors on the public chain use ancestorHash values four blocks prior to their time of issuance. Four blocks after the attacking fork, the attack chain will be entirely absent of those public transactions (thus approaching the ‘none’ option).

This scenario forces the hand of the attacker away from a targeted attack with a single victim toward an attack that jeapordizes the interests of all transactors during that time. Although risk is increased for the public users in this scenario, so too – and at a larger, aggregated, magnitude – is the risk for the attacker in the potential for a counterattack on behalf of the original public chain.

Redundancy to chainId

This pattern can be understood as a correlate of EIP-155’s chainId specification. EIP155 defines the restriction of transactions between chains; limiting the applicability of any EIP-155 transaction to a chain with the annotated ChainID. ancestorHash further restricts transaction application to some subsection (“segment”) of a chain defined under EIP-155.

From this constraint hierarchy, we note that an alternative implementation of ancestorHash could make chainId conceptually redundant.

So why keep chainId?

chainId is maintained as an invariant because:

  • The use of the transaction type proposed by this EIP is optional, implying the continued necessity of chainId in the protocol infrastructure and tooling for legacy and other transaction types.
  • The presence of ancestorHash in the transaction type proposed by this EIP is optional. If the value is not filled by an RCC transaction, the demand for chainId remains.
  • A chainId value is not necessarily redundant to ancestorHash, namely in cases where forks result in living chains. For example, an ancestorHash reference to block 1_919_999 would be ambiguous between Ethereum and Ethereum Classic.
  • It would be possible to specify the omission of chainId in case of ancestorHash’s use. This would add infrastructural complexity for the sake of removing the few bytes chainId typically requires; we do not consider this trade-off worth making.
    • chainId is used as the v value (of v,r,s) in the transaction signing scheme; removing or modifying this incurs complexity at a level below encoded transaction fields, demanding additional infrastructural complexity for implementation.

EIP-2930 Inheritance

The EIP-2930 Optional Access List Type Transaction is used as an assumed “base” transaction type for this proposal. However, this is NOT a conceptual dependency; the included accessList portion of this proposal (the only differential from post-EIP-155 legacy transaction fields) can readily be removed. Standing on the shoulders of EIP-2930 is only intended to support and further the adoption of next-generation transactions.

Signature target

The signature signs over the transaction type as well as the transaction data. This is done to ensure that the transaction cannot be “re-interpreted” as a transaction of a different type.

Backwards Compatibility

There are no known backward compatibility issues.

Security Considerations

Validation costs

Validation of ancestorHash demands the assertion of a positive database hit by block hash. This requires that the chain validator fills the role of a chain reader. This necessary lookup can be cached (and maybe already is for some clients), but we must expect less than 100% hits on cached values, since the lookup value is arbitrary. With that in mind, however, the value provided to a transaction using a deep ancestorHash is increasingly marginal, so we should expect most transactions using this field to use a relatively small set of common, shallow, cache-friendly values.

Transaction size increase

The proposed additional fields, if used, increase transaction size by 32 bytes.

Copyright and related rights waved via CC0.