github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/architecture/adr-023-ABCI-propose-tx.md (about)

     1  # ADR 023: ABCI `ProposeTx` Method
     2  
     3  ## Changelog
     4  
     5  25-06-2018: Initial draft based on [#1776](https://github.com/tendermint/tendermint/issues/1776)
     6  
     7  ## Context
     8  
     9  [#1776](https://github.com/tendermint/tendermint/issues/1776) was
    10  opened in relation to implementation of a Plasma child chain using Tendermint
    11  Core as consensus/replication engine.
    12  
    13  Due to the requirements of [Minimal Viable Plasma (MVP)](https://ethresear.ch/t/minimal-viable-plasma/426) and [Plasma Cash](https://ethresear.ch/t/plasma-cash-plasma-with-much-less-per-user-data-checking/1298), it is necessary for ABCI apps to have a mechanism to handle the following cases (more may emerge in the near future):
    14  
    15  1. `deposit` transactions on the Root Chain, which must consist of a block
    16     with a single transaction, where there are no inputs and only one output
    17     made in favour of the depositor. In this case, a `block` consists of
    18     a transaction with the following shape:
    19  
    20     ```
    21     [0, 0, 0, 0, #input1 - zeroed out
    22      0, 0, 0, 0, #input2 - zeroed out
    23      <depositor_address>, <amount>, #output1 - in favour of depositor
    24      0, 0, #output2 - zeroed out
    25      <fee>,
    26     ]
    27     ```
    28  
    29     `exit` transactions may also be treated in a similar manner, wherein the
    30     input is the UTXO being exited on the Root Chain, and the output belongs to
    31     a reserved "burn" address, e.g., `0x0`. In such cases, it is favorable for
    32     the containing block to only hold a single transaction that may receive
    33     special treatment.
    34  
    35  2. Other "internal" transactions on the child chain, which may be initiated
    36     unilaterally. The most basic example of is a coinbase transaction
    37     implementing validator node incentives, but may also be app-specific. In
    38     these cases, it may be favorable for such transactions to
    39     be ordered in a specific manner, e.g., coinbase transactions will always be
    40     at index 0. In general, such strategies increase the determinism and
    41     predictability of blockchain applications.
    42  
    43  While it is possible to deal with the cases enumerated above using the
    44  existing ABCI, currently available result in suboptimal workarounds. Two are
    45  explained in greater detail below.
    46  
    47  ### Solution 1: App state-based Plasma chain
    48  
    49  In this work around, the app maintains a `PlasmaStore` with a corresponding
    50  `Keeper`. The PlasmaStore is responsible for maintaing a second, separate
    51  blockchain that complies with the MVP specification, including `deposit`
    52  blocks and other "internal" transactions. These "virtual" blocks are then broadcasted
    53  to the Root Chain.
    54  
    55  This naive approach is, however, fundamentally flawed, as it by definition
    56  diverges from the canonical chain maintained by Tendermint. This is further
    57  exacerbated if the business logic for generating such transactions is
    58  potentially non-deterministic, as this should not even be done in
    59  `Begin/EndBlock`, which may, as a result, break consensus guarantees.
    60  
    61  Additinoally, this has serious implications for "watchers" - independent third parties,
    62  or even an auxilliary blockchain, responsible for ensuring that blocks recorded
    63  on the Root Chain are consistent with the Plasma chain's. Since, in this case,
    64  the Plasma chain is inconsistent with the canonical one maintained by Tendermint
    65  Core, it seems that there exists no compact means of verifying the legitimacy of
    66  the Plasma chain without replaying every state transition from genesis (!).
    67  
    68  ### Solution 2: Broadcast to Tendermint Core from ABCI app
    69  
    70  This approach is inspired by `tendermint`, in which Ethereum transactions are
    71  relayed to Tendermint Core. It requires the app to maintain a client connection
    72  to the consensus engine.
    73  
    74  Whenever an "internal" transaction needs to be created, the proposer of the
    75  current block broadcasts the transaction or transactions to Tendermint as
    76  needed in order to ensure that the Tendermint chain and Plasma chain are
    77  completely consistent.
    78  
    79  This allows "internal" transactions to pass through the full consensus
    80  process, and can be validated in methods like `CheckTx`, i.e., signed by the
    81  proposer, is the semantically correct, etc. Note that this involves informing
    82  the ABCI app of the block proposer, which was temporarily hacked in as a means
    83  of conducting this experiment, although this should not be necessary when the
    84  current proposer is passed to `BeginBlock`.
    85  
    86  It is much easier to relay these transactions directly to the Root
    87  Chain smart contract and/or maintain a "compressed" auxiliary chain comprised
    88  of Plasma-friendly blocks that 100% reflect the canonical (Tendermint)
    89  blockchain. Unfortunately, this approach not idiomatic (i.e., utilises the
    90  Tendermint consensus engine in unintended ways). Additionally, it does not
    91  allow the application developer to:
    92  
    93  - Control the _ordering_ of transactions in the proposed block (e.g., index 0,
    94    or 0 to `n` for coinbase transactions)
    95  - Control the _number_ of transactions in the block (e.g., when a `deposit`
    96    block is required)
    97  
    98  Since determinism is of utmost importance in blockchain engineering, this approach,
    99  while more viable, should also not be considered as fit for production.
   100  
   101  ## Decision
   102  
   103  ### `ProposeTx`
   104  
   105  In order to address the difficulties described above, the ABCI interface must
   106  expose an additional method, tentatively named `ProposeTx`.
   107  
   108  It should have the following signature:
   109  
   110  ```
   111  ProposeTx(RequestProposeTx) ResponseProposeTx
   112  ```
   113  
   114  Where `RequestProposeTx` and `ResponseProposeTx` are `message`s with the
   115  following shapes:
   116  
   117  ```
   118  message RequestProposeTx {
   119    int64 next_block_height = 1; // height of the block the proposed tx would be part of
   120    Validator proposer = 2; // the proposer details
   121  }
   122  
   123  message ResponseProposeTx {
   124    int64 num_tx = 1; // the number of tx to include in proposed block
   125    repeated bytes txs = 2; // ordered transaction data to include in block
   126    bool exclusive = 3; // whether the block should include other transactions (from `mempool`)
   127  }
   128  ```
   129  
   130  `ProposeTx` would be called by before `mempool.Reap` at this
   131  [line](https://github.com/tendermint/tendermint/blob/9cd9f3338bc80a12590631632c23c8dbe3ff5c34/consensus/state.go#L935).
   132  Depending on whether `exclusive` is `true` or `false`, the proposed
   133  transactions are then pushed on top of the transactions received from
   134  `mempool.Reap`.
   135  
   136  ### `DeliverTx`
   137  
   138  Since the list of `tx` received from `ProposeTx` are _not_ passed through `CheckTx`,
   139  it is probably a good idea to provide a means of differentiatiating "internal" transactions
   140  from user-generated ones, in case the app developer needs/wants to take extra measures to
   141  ensure validity of the proposed transactions.
   142  
   143  Therefore, the `RequestDeliverTx` message should be changed to provide an additional flag, like so:
   144  
   145  ```
   146  message RequestDeliverTx {
   147  	bytes tx = 1;
   148  	bool internal = 2;
   149  }
   150  ```
   151  
   152  Alternatively, an additional method `DeliverProposeTx` may be added as an accompanient to
   153  `ProposeTx`. However, it is not clear at this stage if this additional overhead is necessary
   154  to preserve consensus guarantees given that a simple flag may suffice for now.
   155  
   156  ## Status
   157  
   158  Pending
   159  
   160  ## Consequences
   161  
   162  ### Positive
   163  
   164  - Tendermint ABCI apps will be able to function as minimally viable Plasma chains.
   165  - It will thereby become possible to add an extension to `cosmos-sdk` to enable
   166    ABCI apps to support both IBC and Plasma, maximising interop.
   167  - ABCI apps will have great control and flexibility in managing blockchain state,
   168    without having to resort to non-deterministic hacks and/or unsafe workarounds
   169  
   170  ### Negative
   171  
   172  - Maintenance overhead of exposing additional ABCI method
   173  - Potential security issues that may have been overlooked and must now be tested extensively
   174  
   175  ### Neutral
   176  
   177  - ABCI developers must deal with increased (albeit nominal) API surface area.
   178  
   179  ## References
   180  
   181  - [#1776 Plasma and "Internal" Transactions in ABCI Apps](https://github.com/tendermint/tendermint/issues/1776)
   182  - [Minimal Viable Plasma](https://ethresear.ch/t/minimal-viable-plasma/426)
   183  - [Plasma Cash: Plasma with much less per-user data checking](https://ethresear.ch/t/plasma-cash-plasma-with-much-less-per-user-data-checking/1298)