Full Specification

The detailed specification on the Job data structure

Job data structure

Job config

To achieve efficiency and save on gas during execution, all manipulations with the Job structure are performed in assembly inserts. The binary representation of struct Job is as follows:

0x                       |    name        | size int | bytes |  bits     
00000000                 | lastExecAt     |  uint32  |   4   |  0-31     
000000                   | interval       |  uint24  |   3   |  32-55    
00                       | calldataSource |  uint8   |   1   |  56-63    
00000000                 | fixedReward    |  uint32  |   4   |  64-95    
0000                     | rewardPct      |  uint16  |   2   |  96-111   
0000000000000000000000   | nativeCredits  |  uint88  |   11  |  112-199  
0000                     | maxBaseFeeGwei |  uint16  |   2   |  200-215  
00000000                 | selector       |  uint32  |   4   |  216-247  
00                       | config         |  uint8   |   1   |  248-255

Job with calldata config

When the job is invoked with some calldata (even if it is just the selector), it is always padded with a few fields, yielding a special binary representation of the calldata as well; the structure is given below.

0x                       |        name       | size int  | bytes |   bits    |
00000000                 | selector          |  uint32   |   4   |  0-31     |
0000...0000 x40          | JobContractAddress|  uint160  |   20  |  32-191   |
000000                   | jobId             |  uint24   |   3   |  192-215  |
00                       | config            |  uint8    |   1   |  216-225  |
000000                   | keeperId          |  uint24   |   3   |  226-249  |
0000... >=1              | executionCalldata |  bytes    |  >=1  |  250-any  |

Here the executionCalldata field contains the calldata proper that is forwarded to the target contract; for Selector jobs, for instance, this field is occupied solely by the four bytes of the target method selector, for Resolver jobs it contains the ad hoc calldata to pass to the target contract, and for the Predefined Calldata jobs, it is absent since the fixed calldata is fetched from the job properties inside the execution call.

Config byte

The Job configuration, expanded as a nested struct in the short specification, is a single byte inside the Job structure and defines the properties of the Job. The bits are allocated consecutively in the uint8 config. The structure of this byte is given below.

0x |               name               | binary
01 | CFG_ACTIVE                       | 00000001
02 | CFG_USE_JOB_OWNER_CREDITS        | 00000010
04 | CFG_ASSERT_RESOLVER_SELECTOR     | 00000100
08 | CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT | 00001000
  • CFG_ACTIVEFlag of a job being active (i.e., admissible for execution given satisfaction of specified logic).

  • CFG_USE_JOB_OWNER_CREDITSWhether to use job owner credits in native tokens for payment. This makes a hard switch from using job credits to using job owner credits and not just enables it as an option.

  • CFG_ASSERT_RESOLVER_SELECTORIndicates whether to enforce the selector of a resolver job function matching between the calldata passed by the Keeper and the job binary representation. This may be desirable because under the hood, resolver jobs work like PRE_DEFINED jobs, except the calldata is provided by the Keeper. It would therefore be possible for a malicious Keeper to supply a different selector, which is not checkable unless this flag is set to True. Has no bearing on interval jobs, since for them, the calldata is fixed.

  • CFG_CHECK_KEEPER_MIN_CVP_DEPOSITWhether to enforce conformance of the stake of keepers and slashers to the minimum required stake of the job.

Last updated