- Proposal Name: Execution Outcome
- Start Date: 2019-09-23
- NEP PR: [nearprotocol/neps#0017](https://github.com/nearprotocol/neps/pull/17)
- Issue(s): https://github.com/nearprotocol/nearcore/issues/1307

# Summary
[summary]: #summary

Refactor current TransactionResult/TransactionLog/FinalTransactionResult to improve naming, deduplicate results and provide
results resolution by the front-end for async-calls.

# Motivation
[motivation]: #motivation

Right now the contract calls 2 promises and doesn't return a value, the front-end will return one of the promises results as an execution result. It's because we return the last result from final transaction result. With the current API, it's impossible to know what is the actual result of the contract execution.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

Here is the proposed Rust structures. Highlights:
- Rename `TransactionResult` to `ExecutionOutcome` since it's used for transactions and receipts
- Rename `TransactionStatus` and merge it with result into `ExecutionResult`.
- In case of success `ExecutionStatus` can either be a value of a receipt_id. This helps to resolve the
  actual returned value by the transaction from async calls, e.g. `A->B->A->C` should return result from `C`.
  Also in distinguish result in case of forks, e.g. `A` calls `B` and calls `C`, but returns a result from `B`.
  Currently there is no way to know.
- Rename `TransactionLog` to `ExecutionOutcomeWithId` which is `ExecutionOutcome` with receipt_id
  or transaction hash. Probably needs a better name.
- Rename `FinalTransactionResult` to `FinalExecutionOutcome`.
- Update `FinalTransactionStatus` to `FinalExecutionStatus`.
- Provide final resolved returned result directly, so the front-end doesn't need to traverse the receipt tree.
  We may also expose the error directly in the execution result.
- Split into final outcome into transaction and receipts.

### NEW

- The `FinalExecutionStatus` contains the early result even if some dependent receipts are not yet executed. Most function call
transactions contain 2 receipts. The 1st receipt is execution, the 2nd is the refund. Before this change, the transaction was
not resolved until the 2nd receipt was executed. After this change, the `FinalExecutionOutcome` will have
`FinalTransactionStatus::SuccessValue("")` after the execution of the 1st receipt, while the 2nd receipt execution outcome status is still `Pending`.
This helps to get the transaction result on the front-end faster without waiting for all refunds.

```rust
pub struct ExecutionOutcome {
    /// Execution status. Contains the result in case of successful execution.
    pub status: ExecutionStatus,
    /// Logs from this transaction or receipt.
    pub logs: Vec<LogEntry>,
    /// Receipt IDs generated by this transaction or receipt.
    pub receipt_ids: Vec<CryptoHash>,
    /// The amount of the gas burnt by the given transaction or receipt.
    pub gas_burnt: Gas,
}

/// The status of execution for a transaction or a receipt.
pub enum ExecutionStatus {
    /// The execution is pending.
    Pending,
    /// The execution has failed.
    Failure,
    /// The final action succeeded and returned some value or an empty vec.
    SuccessValue(Vec<u8>),
    /// The final action of the receipt returned a promise or the signed transaction was converted
    /// to a receipt. Contains the receipt_id of the generated receipt.
    SuccessReceiptId(CryptoHash),
}

// TODO: Need a better name
pub struct ExecutionOutcomeWithId {
    /// The transaction hash or the receipt ID.
    pub id: CryptoHash,
    pub outcome: ExecutionOutcome,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub enum FinalExecutionStatus {
    /// The execution has not yet started.
    NotStarted,
    /// The execution has started and still going.
    Started,
    /// The execution has failed.
    Failure,
    /// The execution has succeeded and returned some value or an empty vec in base64.
    SuccessValue(String),
}

pub struct FinalExecutionOutcome {
    /// Execution status. Contains the result in case of successful execution.
    pub status: FinalExecutionStatus,
    /// The execution outcome of the signed transaction.
    pub transaction: ExecutionOutcomeWithId,
    /// The execution outcome of receipts.
    pub receipts: Vec<ExecutionOutcomeWithId>,
}
```
