Owners: @David Rusu

Reviewers: 🟨@Álvaro Castro-Castilla

Design Rationale

Zone Execution can be incredibly valuable, we want to allow Zones to capture and re-distribute this value by giving them a robust interface for specifying execution rights. Additionally, knowing in advance who will execute a given zone can give us the opportunity to co-ordinate cross-zone transactions (PACTs)

Since co-ordinating cross zone transactions is our holy grail, we must choose a common timeline that all zones can agree with. For example, if we were to choose Zone iteration ranges as the unit of time that execution tickets are created over, then each Zone may evolve at it’s own pace, this can make it difficult to try to line up tickets for multiple zones in order to co-ordinate a PACT across all of them.

Instead, we choose to define execution tickets in terms of block ranges and ask Validators to enforce that zone transitions executed with a ticket only appear within the ticket block range.

The details of how tickets are assigned are left up to the Zone to design we only specify the minimum interface required such that a validator can enforce execution happens within the target block range.

Specification

Execution Ticket

An Execution Ticket is a mechanism that can be used by Zones to give exclusive execution rights to some entity for a pre-specified block range. Zones can distribute these tickets in any way they see fit, e.g. selling them in an auction, distributing them round robin to a permissioned set of executors, etc.

Tickets are enforced by Validators by ensuring that the ZoneTransition making use of this ticket appears in a block within the tickets block range.

struct ExecutionTicket {
  block_start: u64,
  block_end: u64,
}

Zone Transition

Zone Transitions now expose the ticket that was used to prove the zone transition (if one was used).

struct ZoneTransition {
  // ... zone transition fields
  zone: ZoneID,
  ticket: Option<ExecutionTicket>, // the ticket used to perform this transition (if any)
}

Modification to Block Processing Rules

If a ticket was used in executing the Zone Transition, Validators will enforce that the block height is within the ticket block range

impl ValidatorState {
	fn on_block(&mut self, block: Block) {
		// validate all zone transitions
		
		for { zone, ticket, ... } in block.zone_transitions() {
		  // ... existing zone tranistion validations

		  // then verify that if this zone transition was executed via ticket,
		  // the block falls within the ticket's block range
		  if Some(ExecutionTicket { block_start, block_end }) = ticket {
		    if !(block_start <= block.height < block_end) {
			    // ticket is not valid for this block range, drop the block
			    return
		    }
		  }
		}
}