Skip to content

Commit

Permalink
Add batch run to EVM FLIP (#257)
Browse files Browse the repository at this point in the history
Update 20231116-evm-support.md
  • Loading branch information
sideninja authored Apr 29, 2024
1 parent 13cc05f commit a0e9aac
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions protocol/20231116-evm-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,13 @@ fun main(bytes: [UInt8; 20]) {
}
```

`run` is the next crucial function in this contract which runs RLP-encoded EVM transactions. If the interaction with “Flow EVM” is successful and it changes the state, a new Flow-EVM block is formed and its data is emitted as a Cadence event. Using `run` limits EVM block to a single EVM transaction, a future `batchRun` provides option for batching EVM transaction execution.
`run` is the next crucial function in this contract which runs RLP-encoded EVM transactions. If the interaction with “Flow EVM” is successful and it changes the state, a new Flow-EVM block is formed and its data is emitted as a Cadence event. Using `run` limits EVM block to a single EVM transaction, a `batchRun` provides option for batching EVM transaction execution in a single block. Using batch run you can provide an array of RLP-encoded EVM transactions as input and they will be all executed in a new block, the function will return an array of results `[EVM.Result]` which will be the same length as the array of input transactions and will match the order.

```cadence
// Example of tx wrapping
import EVM from <ServiceAddress>
transaction(rlpEncodedTransaction: [UInt8], coinbaseBytes: [UInt8; 20]) {
prepare(signer: AuthAccount) {
execute {
let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
let result = EVM.run(tx: rlpEncodedTransaction, coinbase: coinbase)
assert(
Expand All @@ -89,6 +87,24 @@ transaction(rlpEncodedTransaction: [UInt8], coinbaseBytes: [UInt8; 20]) {
}
```

Example of batch run:
```
import EVM from <ServiceAddress>
transaction(rlpEncodedTransactions: [[UInt8]], coinbaseBytes: [UInt8; 20]) {
execute {
let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
let results = EVM.batchRun(txs: txs, coinbase: coinbase)
assert(results.length == txs.length, message: "invalid result length")
for res in results {
assert(res.status == EVM.Status.successful, message: "unexpected status")
}
}
}
```

Note that calling EVM.run doesn't revert the outter flow transaction and it requires the developer to take proper action based on the result.Status. Execution of a rlp encoded transaction result in one of these cases:
- `Status.invalid`: The execution of an evm transaction/call has failed at the validation step (e.g. nonce mismatch). An invalid transaction/call is rejected to be executed or be included in a block (no state change).
- `Status.failed`: The execution of an evm transaction/call has been successful but the vm has reported an error as the outcome of execution (e.g. running out of gas). A failed tx/call is included in a block.
Expand Down Expand Up @@ -554,6 +570,17 @@ contract EVM {
return runResult
}
/// Runs a batch of RLP-encoded EVM transactions, deducts the gas fees,
/// and deposits the gas fees into the provided coinbase address.
/// An invalid transaction is not executed and not included in the block.
access(all)
fun batchRun(txs: [[UInt8]], coinbase: EVMAddress): [Result] {
return InternalEVM.batchRun(
txs: txs,
coinbase: coinbase.bytes,
) as! [Result]
}
access(all)
fun encodeABI(_ values: [AnyStruct]): [UInt8] {
return InternalEVM.encodeABI(values)
Expand Down

0 comments on commit a0e9aac

Please sign in to comment.