Supervisor
Table of Contents
- Overview
- RPC API
- Common types
- Methods
- Errors
- JSON-RPC Error Codes
- Error Code Structure
- Protocol Specific Error Codes
Overview
The supervisor is an implementation detail of OP Stack native interop and is not the only architecture that can be used to implement it. The supervisor is responsible for indexing data from all of the chains in a cluster so that the safety level of executing messages can quickly be determined.
RPC API
Common types
Identifier
The identifier of a message. Corresponds to an Identifier.
Object:
origin
:Address
blockNumber
:HexUint64
logIndex
:HexUint64
timestamp
:HexUint64
chainID
:ChainID
Message
Describes an initiating message.
Object:
identifier
:Identifier
- identifier of the messagepayloadHash
:Hash
-keccak256
hash of the message-payload bytes
ExecutingDescriptor
Describes the context for message verification. Specifically, this helps apply message-expiry rules on message checks.
Object:
timestamp
:HexUint64
- expected timestamp during message execution.timeout
:HexUint64
- optional, requests verification to still hold attimestamp+timeout
(inclusive). The message expiry-window may invalidate messages. Default interpretation is a0
timeout: what is valid attimestamp
may not be valid attimestamp+1
.
HexUint64
STRING
:
Hex-encoded big-endian number, variable length up to 64 bits, prefixed with 0x
.
Int
NUMBER
:
Regular JSON number, always integer. Assumed to always fit in 51 bits.
ChainID
STRING
:
Hex-encoded big-endian number, variable length up to 256 bits, prefixed with 0x
.
Hash
STRING
:
Hex-encoded, fixed-length, representing 32 bytes, prefixed with 0x
.
Bytes
STRING
:
Hex-encoded, variable length (always full bytes, no odd number of nibbles),
representing a bytes list, prefixed with 0x
.
BlockID
Describes a block.
OBJECT
:
hash
:HASH
- block hashnumber
:Int
- block number
BlockRef
Describes a block.
OBJECT
:
hash
:Hash
- block hashnumber
:Int
- block numberparentHash
:Hash
- block parent-hashtimestamp
:Int
- block timestamp
DerivedIDPair
ChainRootInfo
OBJECT
:
chainId
:HexUint64
- The chain ID (Note: this is changing toChainID
soon)canonical
:Hash
- output root at the latest canonical blockpending
:Bytes
- output root preimage
SuperRootResponse
OBJECT
:
crossSafeDerivedFrom
:BlockID
- common derived-from where all chains are cross-safetimestamp
:Int
- The timestamp of the super rootsuperRoot
:Hash
- The root of the super rootversion
:Int
- The version of the responsechains
:ARRAY
ofChainRootInfo
- List of chains included in the super root
SafetyLevel
The safety level of the message. Corresponds to a verifier SafetyLevel.
STRING
, one of:
invalid
unsafe
: equivalent to safety of thelatest
RPC label.cross-unsafe
local-safe
safe
: matching cross-safe, namedsafe
to match the RPC label.finalized
Methods
supervisor_crossDerivedToSource
Parameters:
chainID
:ChainID
derived
:BlockID
Returns: derivedFrom BlockRef
supervisor_localUnsafe
Parameters:
chainID
:ChainID
Returns: BlockID
supervisor_crossSafe
Parameters:
chainID
:ChainID
Returns: DerivedIDPair
supervisor_finalized
Parameters:
chainID
:ChainID
Returns: BlockID
supervisor_finalizedL1
Parameters: (none)
Returns: BlockRef
supervisor_superRootAtTimestamp
Retrieves the super root state at the specified timestamp, which represents the global state across all monitored chains.
Parameters:
timestamp
:HexUint64
Returns: SuperRootResponse
supervisor_syncStatus
Parameters: (none)
Returns: SupervisorSyncStatus
supervisor_allSafeDerivedAt
Returns the last derived block for each chain, from the given L1 block.
Parameters:
derivedFrom
:BlockID
Returns: derived blocks, mapped in a OBJECT
:
- key:
ChainID
- value:
BlockID
supervisor_checkAccessList
Verifies if an access-list, as defined in EIP-2930, references only valid messages.
Message execution in the CrossL2Inbox
that is statically declared in the access-list will not revert.
Access-list contents
Only the CrossL2Inbox
subset of the access-list in the transaction is required,
storage-access by other addresses is not included.
Note that an access-list can contain multiple different storage key lists for the CrossL2Inbox
address.
All storage keys applicable to the CrossL2Inbox
MUST be joined together (preserving ordering),
missing storage-keys breaks inbox safety.
ALL storage-keys in the access-list for the CrossL2Inbox
MUST be checked.
If there is any unrecognized or invalid key, the access-list check MUST fail.
Access-list execution context
The provided execution-context is used to determine validity relative to the provided time constraints, see timestamp invariants.
Since messages expire, validity is not definitive.
To reserve validity for a longer time range, a non-zero timeout
value can be used.
See ExecutingDescriptor
documentation.
As block-builder a timeout
of 0
should be used.
As transaction pre-verifier, a timeout
of 86400
(1 day) should be used.
The transaction should be re-verified or dropped after this time duration,
as it can no longer be safely included in the block due to message-expiry.
Access-list checks
The access-list check errors are not definite state-transition blockers, the RPC based checks can be extra conservative.
I.e. a message that is uncertain to meet the requested safety level may be denied.
Specifically, no attempt may be made to verify messages that are initiated and executed within the same timestamp,
these are invalid
by default.
Advanced block-builders may still choose to include these messages by verifying the intra-block constraints.
supervisor_checkAccessList
contents
Parameters:
inboxEntries
:ARRAY
ofHash
- statically declaredCrossL2Inbox
access entries.minSafety
:SafetyLevel
- minimum required safety, one of:unsafe
: the message exists.cross-unsafe
: the message exists in a cross-unsafe block.local-safe
: the message exists in a local-safe block, not yet cross-verified.safe
: the message exists in a derived block that is cross-verified.finalized
: the message exists in a finalized block.- Other safety levels are invalid and result in an error.
executingDescriptor
:ExecutingDescriptor
- applies as execution-context to all messages.
Returns: RPC error if the minSafety
is not met by one or more of the access entries.
The access-list entries represent messages, and may be incomplete or malformed. Malformed access-lists result in an RPC error.
Errors
The Supervisor RPC API uses a 6-digit error code system that extends standard JSON-RPC error codes while providing additional categorization based on gRPC status codes.
For standard JSON-RPC error codes, refer to Ethereum JSON-RPC Error Reference.
JSON-RPC Error Codes
Error Code Structure
Supervisor error codes follow this structure:
- First 2 digits:
32
(indicating server error, matching JSON-RPC conventions) - Middle 2 digits: gRPC status code category (01-16, zero-padded)
- Last 2 digits: Specific error index within that category (00-99)
For gRPC status codes reference, see gRPC Status Codes.
Protocol Specific Error Codes
-3204XX
DEADLINE_EXCEEDED
errors
-320400
UNINITIALIZED_CHAIN_DATABASE
Happens when a chain database is not initialized yet.
-3205XX
NOT_FOUND
errors
-320500
SKIPPED_DATA
Happens when we try to retrieve data that is not available (pruned). It may also happen if we erroneously skip data, that was not considered a conflict, if the DB is corrupted.
-320501
UNKNOWN_CHAIN
Happens when a chain is unknown, not in the dependency set.
-3206XX
ALREADY_EXISTS
errors
-320600
CONFLICTING_DATA
Happens when we know for sure that there is different canonical data.
-320601
INEFFECTIVE_DATA
Happens when data is accepted as compatible, but did not change anything. This happens when a node is deriving an L2 block we already know of being derived from the given source, but without path to skip forward to newer source blocks without doing the known derivation work first.
-3209XX
FAILED_PRECONDITION
errors
-320900
OUT_OF_ORDER
Happens when you try to add data to the DB, but it does not actually fit onto the latest data (by being too old or new).
-320901
AWAITING_REPLACEMENT_BLOCK
Happens when we know for sure that a replacement block is needed before progress can be made.
-3210XX
ABORTED
errors
-321000
ITER_STOP
Happens in iterator to indicate iteration has to stop. This error might only be used internally and not sent over the network.
-3211XX
OUT_OF_RANGE
errors
-321100
OUT_OF_SCOPE
Happens when data is accessed, but access is not allowed, because of a limited scope. E.g. when limiting scope to L2 blocks derived from a specific subset of the L1 chain.
-3212XX
UNIMPLEMENTED
errors
-321200
CANNOT_GET_PARENT_OF_FIRST_BLOCK_IN_DB
Happens when you try to get the previous block of the first block. E.g. when trying to determine the previous source block for the first L1 block in the database.
-3214XX
UNAVAILABLE
errors
-321401
FUTURE_DATA
Happens when data is just not yet available.
-3215XX
DATA_LOSS
errors
-321500
MISSED_DATA
Happens when we search the DB, know the data may be there, but is not (e.g. different revision).
-321501
DATA_CORRUPTION
Happens when the underlying DB has some I/O issue.